Guida avanzata di scripting Bash: Un'approfondita esplorazione dell'arte dello scripting di shell | ||
---|---|---|
Indietro | Capitolo 33. Miscellanea | Avanti |
Può uno script richiamare sé stesso ricorsivamente? Certo.
Esempio 33-8. Un (inutile) script che richiama sé stesso ricorsivamente
#!/bin/bash # recurse.sh # Può uno script richiamare sé stesso ricorsivamente? # Sì, ma può essere di qualche uso pratico? # (Vedi il successivo.) INTERVALLO=10 VALMAX=9 i=$RANDOM let "i %= $INTERVALLO" # Genera un numero casuale compreso #+ tra 0 e $INTERVALLO - 1. if [ "$i" -lt "$VALMAX" ] then echo "i = $i" ./$0 # Lo script genera ricorsivamente una nuova istanza #+ di sé stesso. fi # Ogni script figlio fa esattamente la stessa #+ cosa, finché $i non diventa uguale a $VALMAX. # L'uso di un ciclo "while", invece della verifica "if/then", provoca problemi. # Spiegate perché. exit 0 # Nota: # ---- # Lo script, per funzionare correttamente, deve avere il permesso di esecuzione. # Questo anche nel caso in cui venga invocato con il comando "sh". # Spiegate perché. |
Esempio 33-9. Un (utile) script che richiama sé stesso ricorsivamente
#!/bin/bash # pb.sh: phone book # Scritto da Rick Boivie e usato con il consenso dell'autore. # Modifiche effettuate dall'autore de Guida ASB. MINARG=1 # Lo script ha bisogno di almeno un argomento. FILEDATI=./phonebook # Deve esistere un file dati di nome "phonebook" #+ nella directory di lavoro corrente. NOMEPROG=$0 E_NON_ARG=70 # Errore di nessun argomento. if [ $# -lt $MINARG ]; then echo "Utilizzo: "$NOMEPROG" filedati" exit $E_NON_ARG fi if [ $# -eq $MINARG ]; then grep $1 "$FILEDATI" # 'grep' visualizza un messaggio d'errore se $FILEDATI non esiste. else ( shift; "$NOMEPROG" $* ) | grep $1 # Lo script richiama sé stesso ricorsivamente. fi exit 0 # Lo script termina qui. # Quindi, è corretto mettere #+ dati e commenti senza il # oltre questo punto. # ------------------------------------------------------------------------- # Un estratto del file dati "phonebook": John Doe 1555 Main St., Baltimore, MD 21228 (410) 222-3333 Mary Moe 9899 Jones Blvd., Warren, NH 03787 (603) 898-3232 Richard Roe 856 E. 7th St., New York, NY 10009 (212) 333-4567 Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678 Zoe Zenobia 4481 N. Baker St., San Francisco, SF 94338 (415) 501-1631 # ------------------------------------------------------------------------- $bash pb.sh Roe Richard Roe 856 E. 7th St., New York, NY 10009 (212) 333-4567 Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678 $bash pb.sh Roe Sam Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678 # Quando vengono passati più argomenti allo script, #+ viene visualizzata *solo* la/e riga/he contenente tutti gli argomenti. |
Esempio 33-10. Un altro (utile) script che richiama sé stesso ricorsivamente
#!/bin/bash # usrmnt.sh, scritto da Anthony Richardson # Utilizzato con il permesso dell'autore. # utilizzo: usrmnt.sh # descrizione: monta un dispositivo, l'utente cho lo invoca deve essere elencato # nel gruppo MNTUSERS nel file /etc/sudoers. # -------------------------------------------------------------------- # Si tratta dello script usermount che riesegue se stesso usando sudo. # Un utente con i permessi appropriati deve digitare semplicemente # usermount /dev/fd0 /mnt/floppy # invece di # sudo usermount /dev/fd0 /mnt/floppy # Utilizzo questa tecnica per tutti gli #+ script sudo perché la trovo conveniente. # -------------------------------------------------------------------- # Se la variabile SUDO_COMMAND non è impostata, significa che non lo si #+ sta eseguendo attraverso sudo, che quindi va richiamato. Vengono passati #+ i veri id utente e di gruppo . . . if [ -z "$SUDO_COMMAND" ] then mntusr=$(id -u) grpusr=$(id -g) sudo $0 $* exit 0 fi # Verrà eseguita questa riga solo se lo si sta eseguendo con sudo. /bin/mount $* -o uid=$mntusr,gid=$grpusr exit 0 # Note aggiuntive (dell'autore dello script): # ------------------------------------------------- # 1) Linux consente l'uso dell'opzione "users" nel file /etc/fstab, # quindi qualsiasi utente può montare un certo dispositivo. # Ma, su un server, è preferibile consentire l'accesso ai dispositivi # solo a pochi individui. # Trovo che usare sudo dia un maggior controllo. # 2) Trovo anche che, per ottenere questo risultato, sudo sia più # conveniente che utilizzare i gruppi. # 3) Questo metodo fornisce, a tutti coloro dotati dei corretti permessi, # l'accesso root al comando mount, quindi fate attenzione a chi lo # concedete. # È possibile ottenere un controllo ancora più preciso # utilizzando questa tecnica in differenti script ciascono inerente a # mntfloppy, mntcdrom e mntsamba. |
Troppi livelli di ricorsività possono esaurire lo spazio di stack dello script, provocando un segmentation fault. |