È una vecchia citazione, ma penso che questo principio dell'inventore di Perl Larry Wall sia ancora valido:
"Il programmatore pigro riutilizzerà tutto ciò che può per portare a termine il proprio lavoro. Questa virtù porta al riutilizzo del codice incoraggiando la scrittura del codice una sola volta."
— Larry Wall, "Le tre virtù di un programmatore"
Diciamo che ti stanchi di digitare la stessa sequenza di comandi e finalmente crei un simpatico script di shell per eseguire le cose con meno sequenze di tasti. Ma a volte vuoi eseguirlo con argomenti diversi e sicuramente non voglio duplicare il tuo fantastico script. È necessario un modo per fornire e utilizzare argomenti dalla riga di comando. Questo articolo copre esattamente questo.
Elabora input di script
Gli script della shell hanno accesso ad alcune variabili "magiche" dall'ambiente:
$0
- Il nome dello script$1
- Il primo argomento inviato allo script$2
- Il secondo argomento inviato allo script$3
- Il terzo argomento... e così via$#
- Il numero di argomenti forniti$@
- Un elenco di tutti gli argomenti forniti
#!/bin/bash
if [ $# -eq 0 ];
then
echo "$0: Missing arguments"
exit 1
elif [ $# -gt 2 ];
then
echo "$0: Too many arguments: $@"
exit 1
else
echo "We got some argument(s)"
echo "==========================="
echo "Number of arguments.: $#"
echo "List of arguments...: $@"
echo "Arg #1..............: $1"
echo "Arg #2..............: $2"
echo "==========================="
fi
echo "And then we do something with $1 $2"
Ecco alcuni esempi di esecuzione di questa operazione con diverse combinazioni di argomenti:
$ ./ex01.sh
./ex01.sh: Missing arguments
$ ./ex01.sh aa
We got some argument(s)
===========================
Number of arguments.: 1
List of arguments...: aa
Arg #1..............: aa
Arg #2..............:
===========================
And then we do something with aa
$ ./ex01.sh aa bb
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: aa bb
Arg #1..............: aa
Arg #2..............: bb
===========================
And then we do something with aa bb
$ ./ex01.sh aa bb cc
./ex01.sh: Too many arguments: aa bb cc
Questo va bene se hai uno o due argomenti. Tuttavia, si noti che il separatore predefinito tra gli argomenti è il carattere Space. E poiché lo spazio è il separatore predefinito per gli argomenti, possono accadere cose interessanti. Ad esempio, questo è ciò che accade se utilizzi le virgolette con più di due argomenti:
$ ./ex01.sh aa "bb cc xx yy zz"
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: aa bb cc xx yy zz
Arg #1..............: aa
Arg #2..............: bb cc xx yy zz
===========================
And then we do something with aa bb cc xx yy zz
Si noti che lo script interpreta bb cc xx yy zz
come uno argomento perché i valori sono racchiusi tra virgolette doppie, il che va bene anche se questo è quello che vuoi.
[ Tieni i tuoi comandi Linux a portata di mano. Scarica il foglio cheat dei comandi avanzati di Linux. ]
Un'altra cosa interessante è quando il tuo script riceve argomenti da variabili . Se la variabile contiene spazi, devi decidere se vuoi quello valore da trattare come argomento singolo o tutte le parti da trattare come argomenti diversi:
$ export AUTHOR="John Lennon"
$ export SONG="Imagine"
$ ./ex01.sh $AUTHOR $SONG
./ex01.sh: Too many arguments: John Lennon Imagine
$ ./ex01.sh "$AUTHOR" "$SONG"
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: John Lennon Imagine
Arg #1..............: John Lennon
Arg #2..............: Imagine
===========================
And then we do something with John Lennon Imagine
Quando invii gli argomenti come variabili senza virgolette, lo script li interpreta tutti come parole separate e "vede" tre argomenti:John , Lennon e Immagina .
Usando le virgolette intorno le variabili hanno fatto sì che lo script ricevesse ogni variabile come un argomento, il che ha più senso in questo caso.
Gestisci molti altri argomenti
Come hai visto, la variabile magica $@
contiene l'elenco di tutti gli argomenti ricevuti dallo script. Puoi usare un ciclo per elaborare tutti gli argomenti:
#!/bin/bash
echo "We received $# argument(s)"
for i in "$@"
do
echo "Arg...: $i"
done
Che ti dà questo:
$ ./ex02.sh a b c e "stuff with spaces"
We received 5 argument(s)
Arg...: a
Arg...: b
Arg...: c
Arg...: e
Arg...: stuff with spaces
Sii intelligente essendo pigro
Le cose importanti quando si tratta di argomenti negli script della shell sono avere una chiara comprensione di:
- Che forma può assumere il contenuto di un argomento?
- Se viene fornita come variabile, cosa ha inserito per te il "mittente" in quella variabile?
- Se è fornito dall'input dell'utente, come puoi assicurarti che l'utente non "rompa" la tua logica?
- Quali argomenti sono accettabili o obbligatori per tuo sceneggiatura?
- Cosa vuoi fare se gli argomenti non sono validi? Lo script potrebbe generare un errore o forse utilizzare valori predefiniti.
Spero che questo ti aiuti a continuare a essere pigro nel modo giusto... migliorando o riutilizzando alcuni dei tuoi script.