Normalmente i programmi, al termine della loro esecuzione, restituiscono un valore numerico intero, detto codice di uscita (exit code).
Si pensi ad esempio al classico "Hello world!":
#include <stdio.h>
int main(int argc, char **argv)
{
printf("Hello, world!\n");
return 0;
}
Dalla shell si può sapere qual è il codice di uscita dell'ultimo programma eseguito tramite il valore della variabile ?.
$ ./hellow
Hello, world!
$ echo $?
0
Molti programmi usano i codici di uscita per comunicare informazioni "nascoste".
Si provi ad esempio a usare grep:
$ grep http /etc/services
www 80/tcp http # WorldWideWeb HTTP
https 443/tcp # http protocol over TLS/SSL
https 443/udp
$ echo $?
0
$ grep nonesistente /etc/services
$ echo $?
1
$ grep qualcosa /file/nonesistente
grep: /file/nonesistente: No such file or directory
$ echo $?
2
Il programma test comunica il proprio risultato solo attraverso il codice di uscita.
$ test -d /home
$ echo $?
0
$ test -d /casa
$ echo $?
1
$ test 4 = 4
$ echo $?
0
$ test 4 = 5
$ echo $?
1
Quando si usa test, bisogna ricordarsi che l'espansione delle variabili viene fatta dalla shell.
$ test A = B
$ test A = B C
bash: test: too many arguments
$ test A = "B C"
$ VAR1="B C"
$ test A = $VAR1
bash: test: too many arguments
$ test A = "$VAR1"
I codici di uscita possono essere usati tramite la cosiddetta "valutazione di corto circuito".
$ test A = B && echo uguali || echo diversi
diversi
$ test A = A && echo uguali || echo diversi
uguali
Quando si usa il comando test in realtà si usa il comando incorporato della Bash.
Inoltre, si tenga presente che esiste anche la forma abbreviata [, sia come programma esterno che come comando interno.
$ [ A = B ] && echo uguali || echo diversi
diversi
$ [ A = A ] && echo uguali || echo diversi
uguali
La bash, inoltre, dispone di un equivalente più semplice da usare, [[.
Gli script della Bash sono semplici file ASCII.
Si possono eseguire in tre modi diversi:
bash mioscript (invocazione esplicita di una subshell)source mioscript o . mioscript (esecuzione nell'ambito della shell corrente)./mioscript o mioscript (esecuzione autonoma, con specificazione o meno del path: funziona a patto che lo script sia stato reso eseguibile)Il debug può essere effettuato mostrando passo l'istruzione che verrà eseguita (prima o dopo l'espansione).
$ ./saluta #esecuzione semplice
ciao, loris!
$ bash -x saluta #debugging con -x
+ echo ciao, 'loris!'
ciao, loris!
$ bash -v saluta #debugging con -v
#!/bin/bash
echo ciao, $USER!
ciao, loris!
Nell'ambito della Bash si fa uso dei classici costrutti della programmazione imperativa:
if ...; then ...; else ...; fi (selezione)while ...; do ...; done (ciclo while)until ...; do ...; done (ciclo while con test negativo)for ... in ...; do ...; done (ciclo for)Si possono inoltre definire funzioni, usare variabili (non tipizzate), ecc.
Si possono ovviamente valutare i parametri della riga di comando.
$0: nome del programma invocato$#: il numero di parametri$1 a $9: gli altri parametri, in ordine${1} a ${$#}: tutti i parametri"... per imparare veramente lo scripting, l’unico modo è quello di scrivere script" (Mendel Cooper, autore della Guida avanzata di scripting Bash)