Capitolo 7. Home sweet /home
7.2. Il vostro ambiente testuale
7.2.5. Gli script di shell
Uno script di shell è, come abbiamo visto negli esempi sulla configurazione della shell, un file
testuale contenente dei comandi della shell. Quando tale file viene utilizzato come primo argomento
non di opzione nell'invocare Bash, e non sono state inserite né l'opzione -c né -s, Bash legge ed
esegue i comandi presi dal file e poi esce. Questo modo di operare crea una shell non interattiva.
Quando Bash esegue uno script di shell, viene attribuito il parametro speciale 0 al nome del file
piuttosto che il nome della shell, e i parametri posizionali (qualsiasi cosa che segua il nome dello
script) vengono fissati sui restanti argomenti, se esistenti. Se invece non sono stati forniti argomenti
aggiuntivi, i parametri posizionali restano indefiniti.
Uno script di shell può essere reso eseguibile usando il comando chmod per accendere il bit di
esecuzione. Quando Bash trova tale file mentre sta cercando in PATH un comando, apre una
sottoshell per eseguirlo. In altri termini, eseguire
nomefile ARGOMENTI
equivale all'esecuzione di
se “nomefile” è uno script di shell eseguibile. Tale sottoshell reinizializza se stessa in modo che il
risultato è come se fosse stata invocata una nuova shell per interpretare lo script, con l'eccezione
che le posizioni dei comandi registrate dalla genitrice (v. hash nelle pagine Info) vengono
mantenute dalla figlia.
Molte versioni di UNIX rendono ciò parte del meccanismo di esecuzione di un comando del
sistema operativo. Se la prima riga di uno script comincia con i due caratteri “#!”, il resto della riga
specifica un interprete per il programma. Così potete indicare bash, awk, perl o qualche altro
interprete o shell e scrivere il resto del file di script in quel linguaggio.
Gli argomenti per l'interprete consistono in un singolo argomento opzionale dopo il nome
dell'interprete nella prima linea del file di script, seguito dal nome del file di script e poi dai
rimanenti argomenti. Bash svolgerà questa azione nei sistemi operativi che non la gestiscono da
loro stessi.
Spesso gli script di Bash iniziano con
#! /bin/bash
(supponendo che Bash sia stata installata in /bin), poiché ciò assicura che Bash verrà utilizzata per
interpretare lo script, anche se eseguito sotto un'altra shell.
7.2.5.2. Alcuni semplici esempi
Uno script molto semplice consiste in un unico comando che saluta l'utente che lo esegue:
[jerry@nowhere ~] cat hello.sh #!/bin/bash
echo "Ciao $USER"
Di fatto lo script è costituito da un solo comando, echo, che usa il valore ($) della variabile
ambientale USER per stampare una frase personalizzata con il nome dell'utente che fornisce il
comando.
Un altro “monolinea”, impiegato per mostrare gli utenti connessi:
#!/bin/bash
who | cut d " " f 1 | sort u− − −
Qui di seguito c'è uno script formato da un numero maggiore di linee che utilizzo per eseguire
copie di sicurezza di tutti i file in una directory. Per prima cosa lo script crea un elenco di tutti i file
presenti nella directory corrente e lo mette nella variabile LIST. Poi imposta il nome della copia per
ciascun file ed infine copia il file. Per ogni file viene stampato un messaggio:
tille:~> cat bin/makebackupfiles.sh #!/bin/bash
# make copies of all files in a directory LIST=`ls`
ORIG=$i DEST=$i.old cp $ORIG $DEST echo "copied $i" done
Inserendo solo una linea come mv * *.old non funziona, come noterete sperimentandola su un
gruppo di file di prova. Un comando echo è stato aggiunto per mostrare dell'attività: esso torna
normalmente utile quando uno script non funziona. Inseritene uno dopo ciascun passaggio dubbio e
scoprirete l'errore in un attimo.
La directory /etc/rc.d/init.d contiene una quantità di esempi. Diamo un occhio a questo script che
controlla il server immaginario ICanSeeYou:
#!/bin/sh
# description: ICanSeeYou allows you to see networked people
# process name: ICanSeeYou
# pidfile: /var/run/ICanSeeYou/ICanSeeYou.pid # config: /etc/ICanSeeYou.cfg
# Source function library. . /etc/rc.d/init.d/functions
# See how (with which arguments) we were called. case "$1" in
start)
echo n "Starting ICanSeeYou: "− daemon ICanSeeYou
echo
touch /var/lock/subsys/ICanSeeYou ;;
stop)
echo n "Shutting down ICanSeeYou: "− killproc ICanSeeYou echo rm f /var/lock/subsys/ICanSeeYou− rm f /var/run/ICanSeeYou/ICanSeeYou.pid− ;; status) status ICanSeeYou ;; restart) $0 stop $0 start ;; *)
echo "Usage: $0 {start|stop|restart|status}" exit 1
esac
exit 0