Guida avanzata di scripting Bash: Un'approfondita esplorazione dell'arte dello scripting di shell | ||
---|---|---|
Indietro | Avanti |
Ci si abitui a scrivere gli script di shell in maniera sistematizzata e strutturata. Anche "al volo" e "scritti sul retro di una busta", gli script trarranno beneficio se si dedicano pochi minuti a pianificare ed organizzare le idee prima di sedersi a codificarle.
Ecco di seguito poche linee guida per lo stile. Non devono essere intese come Regole di stile ufficiali per lo scripting di shell..
Si commenti il codice. I commenti rendono più facile agli altri capirlo (e apprezzarlo) e più semplice la sua manutenzione.
PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}" # Aveva perfettamente senso quando, l'anno scorso, l'avevate scritto, ma #+ adesso è un mistero totale. # (Da Antek Sawicki's "pw.sh" script.) |
Si aggiungano intestazioni descrittive agli script e alle funzioni.
#!/bin/bash #************************************************# # xyz.sh # # scritto da Bozo Bozeman # # 05 luglio 2001 # # # # Cancellazione dei file di progetto. # #************************************************# E_ERRDIR=65 # Directory inesistente. dirprogetti=/home/bozo/projects # Directory da cancellare. # -------------------------------------------------------------------- # # cancella_filep () # # Cancella tutti i file della directory specificata. # # Parametro: $directory_indicata # # Restituisce: 0 in caso di successo, $E_ERRDIR se qualcosa va storto. # # -------------------------------------------------------------------- # cancella_filep () { if [ ! -d "$1" ] # Verifica l'esistenza della directory indicata. then echo "$1 non è una directory." return $E_ERRDIR fi rm -f "$1"/* return 0 # Successo. } cancella_filep $dirprogetti exit 0 |
Si eviti di usare, per i nomi delle costanti letterali, dei "magic number", [1] cioè, costanti "codificate" . Si utilizzino invece nomi di variabile significativi. Ciò renderà gli script più facili da capire e consentirà di effettuare le modifiche e gli aggiornamenti senza il pericolo che l'applicazione non funzioni più correttamente.
if [ -f /var/log/messages ] then ... fi # L'anno successivo decidete di cambiare lo script per #+ verificare /var/log/syslog. # È necessario modificare manualmente lo script, un'occorrenza #+ alla volta, e sperare che tutto funzioni a dovere. # Un modo migliore: FILELOG=/var/log/messages # Basterà cambiare solo questa riga. if [ -f "$FILELOG" ] then ... fi |
Si scelgano nomi descrittivi per le variabili e le funzioni.
ef=`ls -al $nomedir` # Criptico. elenco_file=`ls -al $nomedir` # Meglio. VALMAX=10 # I nomi delle costanti in #+ lettere maiuscole. while [ "$indice" -le "$VALMAX" ] ... E_NONTROVATO=75 # Costanti dei codici d'errore #+ in maiuscolo e con i nomi #+ che iniziano con "E_". if [ ! -e "$nomefile" ] then echo "Il file $nomefile non è stato trovato." exit $E_NONTROVATO fi MAIL_DIRECTORY=/var/spool/mail/bozo # Lettere maiuscole per le variabili #+ d'ambiente. export MAIL_DIRECTORY LeggiRisposta () # Iniziali maiuscole per i nomi di #+ funzione. { prompt=$1 echo -n $prompt read risposta return $risposta } LeggiRisposta "Qual'è il tuo numero preferito? " numero_preferito=$? echo $numero_preferito _variabileutente=23 # Consentito, ma non raccomandato. # È preferibile che i nomi delle variabili definite dall'utente non inizino #+ con un underscore. # Meglio lasciarlo per le variabili di sistema. |
Si faccia uso dei codici di uscita in modo sistematico e significativo.
E_ERR_ARG=65 ... ... exit $E_ERR_ARG |
Ender suggerisce di usare, per gli script di shell, i codici di exit elencati in /usr/include/sysexits.h , sebbene questi si riferiscano alla programmazione in C e C++.
Nell'invocazione di uno script si usino le opzioni standard. Ender propone la serie seguente.
-a Tutto (all): informazioni complete (comprese quelle riguardanti i file nascosti). -b Breve: versione abbreviata, solitamente per altri script. -c Copia, concatena, ecc. -d Giornaliero (daily): informazioni sull'intera giornata, non solo quelle di uno/a specifico/a utente/istanza. -e Esteso/Elaborato: (spesso non comprende informazioni sui file nascosti). -h Aiuto (help): dettagli sull'uso w/desc, info aggiuntive, discussioni. Vedi anche -V. -l Registra l'output dello script. -m Manuale: visualizza la pagina di manuale di un comando di base. -n Numeri: solo dati numerici. -r Ricorsivo: tutti i file di una directory (e/o tutte le sub-directory). -s Impostazioni (setup) & Gestione File: file di configurazione dello script. -u Utilizzo: elenco delle opzioni d'esecuzione dello script. -v Dettaglio (verbose): informazioni dettagliate, più o meno formattate. -V Versione / Licenza / Copy(right|left) / Contributi (anche email). |
Vedi anche la Sezione F.1.
Si suddividano gli script complessi in moduli più semplici. Si faccia uso delle funzioni ogni qual volta se ne presenti l'occasione. Vedi Esempio 34-4.
Non si usi un costrutto complesso dove uno più semplice è sufficiente.
COMANDO if [ $? -eq 0 ] ... # Ridondante e non intuitivo. if COMANDO ... # Più conciso (anche se, forse, non altrettanto leggibile). |
... reading the UNIX source code to the Bourne shell (/bin/sh). I was shocked at how much simple algorithms could be made cryptic, and therefore useless, by a poor choice of code style. I asked myself, "Could someone be proud of this code?" | |
Landon Noll |
[1] | In questo contesto, il termine "magic number" ha un significato completamente diverso dal magic number usato per designare i tipi di file. |