3 581
contributi
(dotglob e nullglob per espansioni di percorso) |
(espansione aritmetica intera) |
||
Riga 207: | Riga 207: | ||
===Quotare (tra virgolette)=== | ===Quotare (tra virgolette)=== | ||
Racchiudere tra virgolette ogni stringa è raccomandabile, anche se non sempre necessario, così da ridurre il numero di caratteri speciali a cui pensare, permettendo allo stesso tempo l'espansione sicura delle variabili e dei comandi. I soli caratteri speciali rimasti sono <code>$</code>, <code>`</code> (ma non l'apice), <code>"</code> e <code>\</code>, che devono essere preceduti dal carattere di escape <code>\</code>. Le sole espansioni permesse all'interno di una stringa quotata sono di variabile/parametro | Racchiudere tra virgolette ogni stringa è raccomandabile, anche se non sempre necessario, così da ridurre il numero di caratteri speciali a cui pensare, permettendo allo stesso tempo l'espansione sicura delle variabili e dei comandi. I soli caratteri speciali rimasti sono <code>$</code>, <code>`</code> (ma non l'apice), <code>"</code> e <code>\</code>, che devono essere preceduti dal carattere di escape <code>\</code>. Le sole espansioni permesse all'interno di una stringa quotata sono quelle di variabile/parametro (già viste), di comando e aritmetiche (spiegate in seguito). | ||
Per esempio: | Per esempio: | ||
Riga 215: | Riga 215: | ||
echo "\"\" \\" # è equivalente a '"" \' | echo "\"\" \\" # è equivalente a '"" \' | ||
echo "$(ls ..)" # Esegue il comando "ls .." e ne stampa l'output | echo "$(ls ..)" # Esegue il comando "ls .." e ne stampa l'output | ||
echo "~ * .[a-z]*" # non effettua le espansioni di tilda e percorso, ma stampa letteralmente | echo "$((2*2))" # Esegue l'espressione aritmetica e stampa 4 | ||
echo "~ * .[a-z]*" # non effettua le espansioni di tilda e percorso, ma stampa letteralmente | |||
echo "{a,b} $'\n'" # stampa letteralmente, senza espansioni | echo "{a,b} $'\n'" # stampa letteralmente, senza espansioni | ||
</pre> | </pre> | ||
Riga 280: | Riga 281: | ||
# Attenzione che il carattere aggiunto dev'essere nell'output del comando | # Attenzione che il carattere aggiunto dev'essere nell'output del comando | ||
nr=$(printf "\n")X # SBAGLIATO, $nr contiene solo X | nr=$(printf "\n")X # SBAGLIATO, $nr contiene solo X | ||
</pre> | |||
==Espansione aritmetica intera== | |||
Permette di compiere operazioni aritmetiche tra interi, ritornando sempre una singola stringa contenente l'intero risultante. Può essere quotata, ma non cambia niente. | |||
La sintassi è: <code>$((...))</code><br/> | |||
All'interno delle parentesi è possibile utilizzare: | |||
* le quattro operazioni: <code>+ - * /</code> | |||
* resto/modulo: <code>%</code> | |||
* potenza: <code>**</code> | |||
* variabili da espandere (contenenti valori interi) | |||
* parentesi per cambiare le priorità degli operatori: <code>( )</code> | |||
Esempio: | |||
<pre> | |||
base=9 | |||
altezza=5 | |||
area=$(($base * $altezza)) | |||
echo "Area rettangolo: ${area}" # Stampa 45 | |||
echo "Area triangolo: $(($area / 2))" # Stampa 22 (RICORDA: solo interi) | |||
</pre> | </pre> | ||
Riga 399: | Riga 420: | ||
<pre> | <pre> | ||
for file in ./*.odt ./*.abw ./*.txt ./*.rtf ./*.doc; do | for file in ./*.odt ./*.abw ./*.txt ./*.rtf ./*.doc; do | ||
</pre> | </pre> | ||
==Redirezione== | ==Redirezione== | ||
Alcune comuni redirezioni (la lista non è esaustiva): | Alcune comuni redirezioni (la lista non è esaustiva), da scriversi dopo un comando: | ||
* '''> file''' scrive l'output sul file (troncandolo, se esiste); | * '''> file''' dopo un comando ne scrive l'output sul file (troncandolo, se esiste); | ||
* '''>> file''' aggiunge al file (creandolo, se non esiste); | * '''>> file''' aggiunge al file (creandolo, se non esiste); | ||
* '''< file''' legge l'input dal file; | * '''< file''' legge l'input dal file; | ||
Riga 453: | Riga 431: | ||
* '''2>&1''' scrive lo standard error sullo standard output; | * '''2>&1''' scrive lo standard error sullo standard output; | ||
* '''&> file''' invia standard output ed error sul file (per aggiungere: '''&>>'''); | * '''&> file''' invia standard output ed error sul file (per aggiungere: '''&>>'''); | ||
* ''' | ''' : pipe che invia l'output | * ''' | ''' : pipe che invia l'output del comando precedente al successivo. Tutti i comandi di una serie di pipe (anche l'ultimo) sono eseguiti in una subshell, e possono stare su righe diverse con la pipe come ultimo carattere. | ||
Esempi: | Esempi: | ||
Riga 510: | Riga 488: | ||
</pre> | </pre> | ||
Si leggano i rispettivi manuali per maggiori informazioni. <code>find</code> ha la possibilità di eseguire altri comandi esterni sui file trovati direttamente con le opzioni -exec ed -execdir, ma la sintassi è più complessa e non supporta più di un processo per volta, come invece <code>xargs</code>. | Si leggano i rispettivi manuali per maggiori informazioni. <code>find</code> ha la possibilità di eseguire altri comandi esterni sui file trovati direttamente con le opzioni -exec ed -execdir, ma la sintassi è più complessa e non supporta più di un processo per volta, come invece <code>xargs</code>. | ||
==Concatenazione e blocchi di comandi== | |||
Più comandi, anche contenenti redirezioni, possono essere concatenati per formarne di più complessi. L'operatore di concatenazione può essere anche l'ultimo di una riga, per facilitare la leggibilità del codice. | |||
; <code>;</code> : separatore di comandi, con cui un comando verrà eseguito a prescindere dal successo del precedente (in uno script è equivalente a un "a capo" e questa è la concatenazione di default) | |||
; <code>&</code> : separatore che esegue il comando precedente in background (ritorna exit status sempre positivo e non riceve input da tastiera), passando al successivo | |||
; <code>&&</code> : operatore logico AND, che va posizionato tra due comandi, il secondo dei quali è eseguito solo se il primo ha esito positivo | |||
Esempio: | |||
<pre> | |||
cd /percorso/dir && comando | |||
</pre> | |||
Attenzione invece alla '''pericolosità''' di: | |||
<pre> | |||
cd /tmp/tmpdir # cambia la cartella corrente in /tmp/tmpdir | |||
# ma se fallisce, quello successivo verrebbe eseguito comunque! | |||
rm -- ./* # cancella tutti i file nella directory corrente | |||
</pre> | |||
; <code>||</code> : operatore logico OR, il secondo comando è eseguito solo se il primo ha effetto negativo (si può usare anche dopo una sequenza di &&, perché ha priorità inferiore): | |||
; <code>{ ... ; }</code> : esegue un blocco di comandi (dopo l'ultimo servono ";" o un "a capo"). È usata nelle funzioni ed è utile per concatenare && e ||: | |||
<pre> | |||
# interrompe la catena se un comando fallisce | |||
cd /tmp/tmpdir && | |||
rm -- ./* && | |||
rmdir -- /tmp/tmpdir || { | |||
# il blocco è eseguito solo se un comando fallisce | |||
retval=$? | |||
echo "ERRORE (exit status: $retval)" >&2 | |||
exit $retval | |||
} | |||
</pre> | |||
; <code>( ... )</code> : esegue il blocco di comandi in una subshell (le variabili vengono ripristinate al loro valore precedente, alla fine del blocco). | |||
===Catturare l'exit status=== | |||
Per catturare lo stato d'uscita di un comando appena eseguito è sufficiente espandere la variabile speciale <code>$?</code>, come già visto. Tuttavia in caso di fallimento del comando, il controllo effettuato via <code>$?</code> avverrebbe soltanto '''dopo''' un blocco con errore (si veda la parte sul debug). | |||
Per evitare che un blocco abbia un exit status diverso da zero, si possono usare le concatenazioni <code>&&</code> e <code>||</code> (oppure un <code>if</code>): | |||
<pre> | |||
comando && | |||
status=0 || # se corretto | |||
status=$? # se sbagliato | |||
</pre> | |||
== Debug integrato == | == Debug integrato == |
contributi