| 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. |