Bash scripting - comandi essenziali: differenze tra le versioni

m
Correzione maiuscola-minuscola
mNessun oggetto della modifica
m (Correzione maiuscola-minuscola)
 
(7 versioni intermedie di 3 utenti non mostrate)
Riga 1: Riga 1:
{{Bash_scripting}}
{{Bash scripting}}
=Comandi essenziali=
__TOC__
I comandi introdotti in questa sezione sono descritti solo limitatamente alla loro sintassi base, così che il loro impiego nelle sezioni successive possa essere facilmente compreso.
I comandi introdotti in questa sezione sono descritti solo limitatamente alla loro sintassi base, così che il loro impiego nelle sezioni successive possa essere facilmente compreso.


La lettura della sezione può essere tralasciata, se si hanno già nozioni basilari di '''bash''', ma la parte sui comandi di output serve anche a giustificare la scelta di <code>printf</code> in luogo del più noto <code>echo</code> come unico comando di output e a spiegarne brevemente la sintassi, almeno per le invocazioni più comuni.
La lettura della sezione può essere tralasciata, se si hanno già nozioni basilari di '''bash''', ma la parte sui comandi di output serve anche a giustificare la scelta di <code>printf</code> in luogo del più noto <code>echo</code> come unico comando di output e a spiegarne brevemente la sintassi, almeno per le invocazioni più comuni.


==Comandi di output: echo e printf==
== Comandi di output: echo e printf ==
Il comando <code>echo</code> è largamente diffuso in Bash per stampare delle stringhe su schermo, perché ha una sintassi più semplice di <code>printf</code> e non risente delle stesse limitazioni della shell sh (''POSIX''), che interpreta ed espande i caratteri di escape (si legga la sezione dedicata) senza che ci sia un modo di stampare letteralmente una stringa (non nota a priori).
Il comando <code>echo</code> è largamente diffuso in Bash per stampare delle stringhe su schermo, perché ha una sintassi più semplice di <code>printf</code> e non risente delle stesse limitazioni della shell sh (''[[POSIX]]''), che interpreta ed espande i caratteri di escape (si legga la sezione dedicata) senza che ci sia un modo di stampare letteralmente una stringa (non nota a priori).


Tuttavia negli script l'uso di <code>echo</code> non è sempre possibile, rendendo necessaria la conoscenza almeno basilare di <code>printf</code>. In particolare, se si vuole stampare il contenuto di $var, '''non''' è sempre corretto scrivere:
Tuttavia negli script l'uso di <code>echo</code> non è sempre possibile, rendendo necessaria la conoscenza almeno basilare di <code>printf</code>. In particolare, se si vuole stampare il contenuto di $var, '''non''' è sempre corretto scrivere:
Riga 19: Riga 19:
In questa guida d'ora in poi si farà riferimento soltanto a <code>printf</code>.
In questa guida d'ora in poi si farà riferimento soltanto a <code>printf</code>.


===Uso di printf===
=== Uso di printf ===
Sintassi: <code>printf formato [ "stringa" ... ]</code>
Sintassi: <code>printf formato [ "stringa" ... ]</code>


Riga 69: Riga 69:
</pre>
</pre>


====Stampa di messagi d'errore====
==== Stampa di messagi d'errore ====
Per i messaggi di errore, benché sia possibile stamparli assieme ai messaggi normali (sullo ''standard output''), è conveniente utilizzare lo ''standard error'' che ne permette la gestione separata. Se nessuna redirezione è specificata, saranno comunque stampati a schermo a prescindere dall'uso di ''standard output'', che è implicito, o ''standard error''.
Per i messaggi di errore, benché sia possibile stamparli assieme ai messaggi normali (sullo ''standard output''), è conveniente utilizzare lo ''standard error'' che ne permette la gestione separata. Se nessuna redirezione è specificata, saranno comunque stampati a schermo a prescindere dall'uso di ''standard output'', che è implicito, o ''standard error''.


Riga 79: Riga 79:
</pre>
</pre>


====Sovrascrivere echo====
==== Sovrascrivere echo ====
Se non si riesce a fare a meno di <code>echo</code> si può sovrascriverlo per gli usi più basilari, così da utilizzare al suo posto <code>printf</code> in modo trasparente, mettendo queste definizioni in cima allo script subito dopo lo ''shebang'':
Se non si riesce a fare a meno di <code>echo</code> si può sovrascriverlo per gli usi più basilari, così da utilizzare al suo posto <code>printf</code> in modo trasparente, mettendo queste definizioni in cima allo script subito dopo lo ''shebang'':
<pre>
<pre>
Riga 111: Riga 111:
</pre>
</pre>


==Condizioni==
== Condizioni ==
Le condizioni nella shell dipendono dal valore di uscita (exit status) di un comando. Si considera successo un exit status corrispondente a 0, ed è equivalente a una condizione vera/soddisfatta, mentre fallimento un exit status con valori diversi da zero, e sono equivalenti a una condizione falsa/non soddisfatta.
Le condizioni nella shell dipendono dal valore di uscita (exit status) di un comando. Si considera successo un exit status corrispondente a 0, ed è equivalente a una condizione vera/soddisfatta, mentre fallimento un exit status con valori diversi da zero, e sono equivalenti a una condizione falsa/non soddisfatta.


Riga 129: Riga 129:
</pre>
</pre>


===Espressioni booleane===
=== Espressioni booleane ===
Le espressioni booleane più basilari, ereditate da ''POSIX'', si possono esprimere con i comandi <code>test</code> e <code>[</code>. L'unica differenza tra i due è che il secondo richiede <code>]</code> come ultimo argomento, ed è preferibile per questioni di leggibilità del codice. D'ora in poi infatti si considera soltanto <code>[ ... ]</code>, e in questa sezione vengono descritte solo le forme più basilari. Per tutte le opzioni supportate si rimanda all'aiuto integrato (<code>help test</code>).
Le espressioni booleane più basilari, ereditate da ''POSIX'', si possono esprimere con i comandi <code>test</code> e <code>[</code>. L'unica differenza tra i due è che il secondo richiede <code>]</code> come ultimo argomento, ed è preferibile per questioni di leggibilità del codice. D'ora in poi infatti si considera soltanto <code>[ ... ]</code>, e in questa sezione vengono descritte solo le forme più basilari. Per tutte le opzioni supportate si rimanda all'aiuto integrato (<code>help test</code>).


Riga 161: Riga 161:


Confronti unari con stringhe contenenti percorsi di file (percorso di default: directory corrente, se mancante):
Confronti unari con stringhe contenenti percorsi di file (percorso di default: directory corrente, se mancante):
* <code>[ -b "$var" ]</code>: vero se il file è un dispositivo a blocchi;
* <code>[ -c "$var" ]</code>: vero se il file è un dispositivo a caratteri;
* <code>[ -d "$var" ]</code>: vero se il file esiste ed è una directory;
* <code>[ -e "$var" ]</code>: vero se il file (file regolare, directory, link simbolico, fifo, socket, ... ) esiste;
* <code>[ -e "$var" ]</code>: vero se il file (file regolare, directory, link simbolico, fifo, socket, ... ) esiste;
* <code>[ -f "$var" ]</code>: vero se il file esiste ed è un file regolare;
* <code>[ -f "$var" ]</code>: vero se il file esiste ed è un file regolare;
* <code>[ -d "$var" ]</code>: vero se il file esiste ed è una directory;
* <code>[ -g "$var" ]</code>: vero se è impostato il bit sgid;
* <code>[ -G "$var" ]</code>: vero se l’id di gruppo del file è uguale al vostro;
* <code>[ -h "$var" ]</code>: vero se il file esiste ed è un link simbolico;
* <code>[ -k "$var" ]</code>: vero se è impostato lo “sticky bit”;
* <code>[ -L "$var" ]</code>: vero se il file esiste ed è un link simbolico;
* <code>[ -N "$var" ]</code>: vero se il file è stato modificato dall’ultima lettura;
* <code>[ -O "$var" ]</code>: vero se si è il proprietario del file;
*<code>[ -p "$var" ]</code>: vero se il file è una pipe (FIFO);
* <code>[ -r "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di lettura;
* <code>[ -r "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di lettura;
*<code>[ -s "$var" ]</code>: vero se il file non è vuoto;
* <code>[ -S "$var" ]</code>: vero se il file è un socket;
* <code>[ -t "$var" ]</code>: vero se il file è associato a un terminale;
* <code>[ -u "$var" ]</code>: vero se è impostato il bit suid;
* <code>[ -w "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di scrittura;
* <code>[ -w "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di scrittura;
* <code>[ -x "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di esecuzione (o accesso per le directory).
* <code>[ -x "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di esecuzione (o accesso per le directory).
Confronti binari con stringhe contenenti percorsi di file:
* <code>[ "$var1" -nt "$var2" ]</code>: vero se il file $var1 è più recente di $var2;
*<code>[ "$var1" -ot "$var2" ]</code>: vero se il file $var1 è più vecchio di $var2;
* <code>[ "$var1" -et "$var2" ]</code>: vero se i file $var1 e $var2 sono degli hard link allo stesso file;
Con il punto esclamativo <code>!</code> (NOT) si inverte il senso dei precedenti confronti.


===Esecuzione condizionata===
=== Esecuzione condizionata ===
Per eseguire un blocco di comandi soltanto se una condizione è soddisfatta si utilizza <code>if</code>, solitamente in combinazione con <code>[...]</code>.
Per eseguire un blocco di comandi soltanto se una condizione è soddisfatta si utilizza <code>if</code>, solitamente in combinazione con <code>[...]</code>.


Riga 194: Riga 215:
</pre>
</pre>


====Controllo degli errori====
==== Controllo degli errori ====
Si ricordi che <code>if</code> accetta un comando qualsiasi come condizione, valutandone l'exit status ed eseguendo il ramo <code>then</code> se ha successo, e quello <code>elif</code>/<code>else</code> immediatamente successivo (se presente) altrimenti. Quindi è un ottimo strumento anche per controllare che un comando venga eseguito senza errori, permettendo anche la terminazione immediata dello script:
Si ricordi che <code>if</code> accetta un comando qualsiasi come condizione, valutandone l'exit status ed eseguendo il ramo <code>then</code> se ha successo, e quello <code>elif</code>/<code>else</code> immediatamente successivo (se presente) altrimenti. Quindi è un ottimo strumento anche per controllare che un comando venga eseguito senza errori, permettendo anche la terminazione immediata dello script:
<pre>
<pre>