Ho appena scoperto che getopt
non è multipiattaforma (in particolare per FreeBSD e Linux). Qual è la soluzione migliore per questo problema?getopt cross-platform per uno script di shell
risposta
Utilizzare getopts
(con una "s").
Secondo Bash FAQ 35:
meno che non sia la versione da util-linux, e si utilizza la sua modalità avanzata, non usare mai getopt (1). getopt non può gestire stringhe di argomenti vuoti o argomenti con spazi bianchi incorporati. Per favore dimentica che è mai esistito.
La shell POSIX (e altri) offrono getopts che è invece sicuro da utilizzare.
Io uso la "S" mnemonica per Shell, getopt "S" è incorporata in BASH –
@Dennis Williamson Si prega di aggiornare la risposta: in base alla voce delle FAQ (aggiornata): ** A meno che non sia la versione di util-linux, e tu usa la sua modalità avanzata, non usare mai getopt (1). ... ** – Florian
@Florian: aggiornato. Grazie. –
La sintassi di base per getopt
è multipiattaforma.
getopt vi: -v -i 100 file
Esistono essenzialmente due versioni del comando getopt
: la versione originale e la versione potenziata GNU. La versione migliorata GNU è retrocompatibile con la versione originale, quindi se si utilizzano solo le funzionalità della versione originale funzionerà con entrambi.
rilevare quale versione di getopt è disponibile
è possibile rilevare che versioni e utilizzare le funzionalità avanzate se la versione GNU, migliorata, è disponibile, e ci si limita alle caratteristiche originali se la versione GNU, migliorata, è non disponibile. La versione avanzata ha un'opzione -T
per testare quale versione è disponibile.
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# GNU enhanced getopt is available
set -- `getopt --long help,output:,version --options ho:v -- "[email protected]"`
else
# Original getopt is available
set -- `getopt ho:v "[email protected]"`
fi
Considerare l'utilizzo di comando integrato shell getopts
(con una "s"), invece, perché è più portatile. Tuttavia, getopts
non supporta le opzioni lunghe (ad esempio --help
).
Se si desiderano opzioni lunghe, utilizzare getopt
e utilizzare il test precedente per verificare se la versione potenziata GNU di getopt
è disponibile o meno. Se la versione avanzata non è disponibile, lo script può degradarsi in modo gradevole utilizzando la versione originale di getopt
(senza supporto per nomi di opzioni lunghe e senza supporto per spazi bianchi) o utilizzando getopts
(senza supporto per nomi di opzioni lunghi).
Utilizzando GNU, migliorata getopt correttamente
Ottenere la versione avanzata GNU per elaborare gli argomenti con uno spazio adeguato è difficile. Ecco come si fa:
ARGS=`getopt --long help,output:,verbose --options ho:v -- "[email protected]"`
if [ $? -ne 0 ]; then
echo "Usage error (use -h for help)" >&2
exit 2
fi
eval set -- $ARGS
# Parameters are now sorted: options appear first, followed by --, then arguments
# e.g. entering: "foo bar" -o abc baz -v
# produces: -o 'abc' -v -- 'foo bar' 'baz'
Il segreto è quello di utilizzare "[email protected]"
dove le virgolette sono molto importanti (in linea 1), e per il eval
impostato comando (in linea 6).
Quindi errori generati da getopt
possono essere rilevati e trattati, la chiamata a getopt
viene eseguita separatamente dalla eval
con i due legati dalla variabile ARGS.
esempio di lavoro completo
PROG=`basename $0`
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# GNU enhanced getopt is available
ARGS=`getopt --name "$PROG" --long help,output:,verbose --options ho:v -- "[email protected]"`
else
# Original getopt is available (no long option names, no whitespace, no sorting)
ARGS=`getopt ho:v "[email protected]"`
fi
if [ $? -ne 0 ]; then
echo "$PROG: usage error (use -h for help)" >&2
exit 2
fi
eval set -- $ARGS
while [ $# -gt 0 ]; do
case "$1" in
-h | --help) HELP=yes;;
-o | --output) OUTFILE="$2"; shift;;
-v | --verbose) VERBOSE=yes;;
--) shift; break;; # end of options
esac
shift
done
if [ $# -gt 0 ]; then
# Remaining parameters can be processed
for ARG in "[email protected]"; do
echo "$PROG: argument: $ARG"
done
fi
echo "$PROG: verbose: $VERBOSE"
echo "$PROG: output: $OUTFILE"
echo "$PROG: help: $HELP"
Questo esempio può essere scaricato dal https://gist.github.com/hoylen/6607180
La tabella di confronto sui Wikipedia's entry on getopts a confronto le diverse caratteristiche.
Sì, 'getopts' (con una s) è un'altra opzione. I puristi della portabilità preferirebbero comunque optare perché i getopts non erano disponibili negli antichi gusci di Bourne prima del 1986, ma questa è una scusa perché la maggior parte/tutte le moderne shell supportano l'opzione. Un motivo migliore è quello di facilitare l'utilizzo del getup GNU migliorato, se disponibile. Il getopt GNU migliorato consente agli operandi di essere combinati con opzioni e supporta nomi di opzioni lunghi (entrambe le funzionalità che getopts non supporta - si veda [tabella di confronto] [1]). – Hoylen
Perché stampa un '-' vuoto quando eseguo 'eval set - $ ARGS'? È molto irritante – Hindol
La funzione getopts Bash incorporato può essere utilizzato per analizzare le opzioni a breve e lungo portabile, vedi:
Using getopts in bash shell script to get long and short command line options
- 1. Blocca commenti in uno script di shell
- 2. Incorporamento awk in uno script di shell
- 3. Cosa significa $ @ in uno script di shell?
- 4. come utilizzare uno script di shell per supervisionare un programma?
- 5. SQLite per script di shell
- 6. Come chiamare uno script di shell e passare argomento da un altro script di shell
- 7. Problemi di comprensione di uno script di shell semplice
- 8. Argomento dello script di shell parsing
- 9. Come passare variabili da uno script di shell ad uno script previsto?
- 10. Esecuzione di uno script di shell bash in java
- 11. Script di shell per inviare e-mail
- 12. Variabili di ambiente globali in uno script di shell
- 13. Pretty-print per script di shell
- 14. Test di unità per script di shell
- 15. Come includere il file in uno script di shell bash
- 16. Chiamare una funzione Python da uno script di shell
- 17. Utilizzo del comando passwd da uno script di shell
- 18. Incorporare un binario eseguibile in uno script di shell
- 19. Come eseguire uno script di shell interattivo usando java runtime?
- 20. nginx - Come eseguire uno script di shell su ogni richiesta?
- 21. Come si esegue uno script di shell come root (sudo)?
- 22. Scrittura di uno script Fish Shell con un argomento facoltativo
- 23. compilatori per gli script di shell
- 24. Come faccio ENV uscita come uno script di shell eseguibile
- 25. Pubblicare un download su bitbucket da uno script di shell
- 26. Come usare arricciatura in uno script di shell?
- 27. Analizza in array in uno script di shell
- 28. Come eseguire uno script di shell utilizzando file docker CMD
- 29. come disabilitare silenziosamente xtrace in uno script di shell?
- 30. Aggiungendo a crontab uno script di shell su Ubuntu
Se hai iniziato utilizzando GNU getopt con lunghe opzioni, ecc, e stanno cercando di rendere il codice esistente portatile con il minor numero di modifiche possibile, quindi è possibile trovare http://stackoverflow.com/a/37087374/324105 utile. – phils