Guida avanzata di scripting Bash: Un'approfondita esplorazione dell'arte dello scripting di shell | ||
---|---|---|
Indietro | Avanti |
I comandi standard UNIX rendono gli script di shell più versatili. La potenza degli script deriva dall'abbinare, in semplici costrutti di programmazione, comandi di sistema e direttive di shell.
I primi comandi che un principiante deve conoscere
Il comando fondamentale per "elencare"
i file. È molto facile sottostimare la potenza di
questo umile comando. Per esempio, l'uso dell'opzione
-R
, ricorsivo, con ls
provvede ad elencare la directory in forma di struttura ad
albero. Altre utili opzioni sono:
-S
, per ordinare l'elenco in base alla dimensione,
-t
, per ordinarlo in base alla data di modifica,
-b
, per mostrare i caratteri di escape e
-i
per mostrare gli inode dei file (vedi Esempio 15-4).
Il comando ls restituisce un exit status diverso da zero quando cerca di elencare un file inesistente.
|
Esempio 15-1. Utilizzare ls per creare un sommario da salvare in un CDR
#!/bin/bash # ex40.sh (burn-cd.sh) # Script per rendere automatica la registrazione di un CDR. VELOC=2 # Potete utilizzare una velocità più elevata #+ se l'hardware la supporta. FILEIMMAGINE=cdimage.iso CONTENUTIFILE=contenuti DISPOSITIVO=cdrom # DISPOSITIVO="0,0" Per le vecchie versioni di cdrecord DEFAULTDIR=/opt # Questa è la directory contenente i dati da registrare. # Accertatevi che esista. # Esercizio: aggiungente un controllo che lo verifichi. # Viene usato il programma "cdrecord" di Joerg Schilling: # http://www.fokus.fhg.de/usr/schilling/cdrecord.html # Se questo script viene eseguito da un utente ordinario va impostato #+ il bit suid di cdrecord (chmod u+s /usr/bin/cdrecord, da root). # Naturalmente questo crea una falla nella sicurezza, anche se non rilevante. if [ -z "$1" ] then DIRECTORY_IMMAGINE=$DEFAULTDIR # Viene usata la directory predefinita se non ne viene specificata #+ alcuna da riga di comando. else DIRECTORY_IMMAGINE=$1 fi # Crea il "sommario" dei file. ls -lRF $DIRECTORY_IMMAGINE > $DIRECTORY_IMMAGINE/$CONTENUTIFILE # L'opzione "l" fornisce un elenco "dettagliato". # L'opzione "R" rende l'elencazione ricorsiva. # L'opzione "F" evidenzia i tipi di file (le directory hanno una #+ "/" dopo il nome). echo "Il sommario è stato creato." # Crea l'immagine del file che verrà registrato sul CDR. mkisofs -r -o $FILEIMMAGINE $DIRECTORY_IMMAGINE echo "È stata creata l'immagine ($FILEIMMAGINE) su file system ISO9660." # Registra il CDR. echo "Sto \"bruciando\" il CD." echo "Siate pazienti, occorre un po' di tempo." cdrecord -v -isosize speed=$VELOC dev=$DISPOSITIVO $FILEIMMAGINE exit $? |
cat è l'acronimo di concatenato, visualizza un file allo stdout. In combinazione con gli operatori di redirezione (> o >>) è comunemente usato per concatenare file.
# Usi di 'cat' cat nomefile # Visualizza il contenudo del file. cat file.1 file.2 file.3 > file.123 # Concatena tre file in uno. |
-n
di cat
numera consecutivamente le righe del/dei file di
riferimento. L'opzione -b
numera solo le
righe non vuote. L'opzione -v
visualizza
i caratteri non stampabili, usando la notazione
^ . L'opzione -s
comprime
tutte le righe vuote consecutive in un'unica riga vuota.
Vedi anche Esempio 15-25 e Esempio 15-21.
In una pipe, risulta più efficiente redirigere lo stdin in un file piuttosto che usare cat.
|
tac è l'inverso di cat e visualizza un file in senso contrario, vale a dire, partendo dalla fine.
inverte ogni riga di un file e la visualizza allo stdout. Non ha lo stesso effetto di tac poiché viene preservato l'ordine delle righe, semplicemente rovescia ciascuna riga (come l'immagine riflessa da uno specchio).
bash$ cat file1.txt Questa è la riga 1. Questa è la riga 2. bash$ tac file1.txt Questa è la riga 2. Questa è la riga 1. bash$ rev file1.txt .1 agir al è atseuQ .2 agir al è atseuQ |
È il comando per la copia dei file. cp file1 file2 copia file1 in file2, sovrascrivendo file2 nel caso esistesse già (vedi Esempio 15-6).
Sono particolarmente utili le opzioni
|
È il comando per lo spostamento di file. È equivalente alla combinazione di cp e rm. Può essere usato per spostare più file in una directory o anche per rinominare una directory. Per alcune dimostrazioni sull'uso di mv in uno script, vedi Esempio 9-19 e Esempio A-2.
Se usato in uno script non interattivo,
mv vuole l'opzione Quando una directory viene spostata in un'altra preesistente, diventa la sottodirectory di quest'ultima.
|
Cancella (rimuove) uno o più file. L'opzione
-f
forza la cancellazione anche dei file
in sola lettura. È utile per evitare l'input
dell'utente in uno script.
Il semplice comando rm non riesce a cancellare i file i cui nomi iniziano con un trattino.
Un modo per riuscirci è far precedere il nome del file che deve essere rimosso da punto-barra.
|
Se usato con l'opzione di ricorsività
|
Cancella una directory. Affinché questo comando funzioni è necessario che la directory non contenga alcun file -- neanche gli "invisibili" dotfile [1].
Crea una nuova directory. Per esempio, mkdir -p progetto/programmi/Dicembre crea la directory indicata. L'opzione -p crea automaticamente tutte le necessarie directory indicate nel percorso.
Modifica gli attributi di un file, o directory, esistente (vedi Esempio 14-12).
chmod +x nomefile # Rende eseguibile "nomefile" per tutti gli utenti. chmod u+s nomefile # Imposta il bit "suid" di "nomefile". # Un utente comune può eseguire "nomefile" con gli stessi privilegi del #+ proprietario del file (Non è applicabile agli script di shell). |
chmod 644 nomefile # Dà al proprietario i permessi di lettura/scrittura su "nomefile", il #+ permesso di sola lettura a tutti gli altri utenti # (modalità ottale). chmod 444 nomefile # Dà a tutti gli utenti il permesso di sola lettura su "nomefile". # Non è consentito, ad un utente che non sia il proprietario del file, #+ (tranne che a root) di modificarlo (usando, per esempio, un editor di testo), #+ e persino il suo proprietario deve forzarne il salvataggio #+ in caso di modifica. # Le stesse limitazioni valgono per la cancellazione del file. |
chmod 1777 nome-directory # Dà a tutti gli utenti i permessi di lettura, scrittura ed esecuzione nella #+ directory, inoltre imposta lo "sticky bit". Questo significa che solo il #+ proprietario della directory, il proprietario del file e, naturalmente, root #+ possono cancellare dei file particolari presenti in quella directory. chmod 111 nome-directory # Dà a tutti gli utenti il permesso di sola esecuzione nella directory. # Questo significa che si possono eseguire e LEGGERE i file di quella #+ directory (il permesso di esecuzione implica necessariamente il permesso #+ di lettura, perché: è impossibile eseguire un file senza essere #+ in grado di leggerlo). # I file, però, non possono essere elencati o effettuarne la ricerca #+ per mezzo del comando "find". # Queste limitazioni non valgono per root. chmod 000 nome-directory # Nessun permesso sulla directory. # I suoi file non possono essere scritti, letti o eseguiti. # Non è neanche possibile elencarli o accedervi con "cd". # Si può, però, rinominare (mv) la directory #+ o cancellarla (rmdir), se vuota. # È anche possibile effettuare dei link simbolici ai suoi file, #+ ma anche tali link non possono essere scritti, letti o eseguiti. # Queste limitazioni non valgono per root |
Modifica (change) gli attributi del file. Ha lo stesso effetto di chmod, visto sopra, ma con sintassi ed opzioni diverse, e funziona solo su un filesystem di tipo ext2.
Un'opzione particolarmente interessante di chattr
è i
. chattr +i
nomefile contrassegna quel file
come immodificabile. Il file non può essere in alcun modo modificato,
soggetto a link o cancellato, neanche da root. Questo
attributo può essere impostato o rimosso solo da
root. In modo simile, l'opzione a
contrassegna il file come scrivibile, ma solo per accodamento.
root# chattr +i file1.txt root# rm file1.txt rm: remove write-protected regular file `file1.txt'? y rm: cannot remove `file1.txt': Operation not permitted |
Se un file ha impostato l'attributo
s
(secure), in caso di cancellazione il/i blocco/hi
che occupava sul disco verrà/anno sovrascritto/i
con degli zero.
Se un file ha impostato l'attributo u
(undelete), in caso di cancellazione sarà ancora possibile
recuperarne il contenuto (non cancellato).
Se un file ha impostato l'attributo c
(compress), viene automaticamente compresso prima della scrittura
su disco e decompresso per la lettura.
Gli attributi di un file impostati con chattr non vengono elencati (se si è usato ls -l). |
Crea dei link a file esistenti. Un "link" è un riferimento a un file, un nome alternativo. Il comando ln permette di fare riferimento al file collegato (linkato) con più di un nome e rappresenta un'alternativa di livello superiore all'uso degli alias (vedi Esempio 4-6).
ln crea semplicemente un riferimento, un puntatore al file, che occupa solo pochi byte.
Il comando ln è usato molto spesso
con l'opzione -s
, simbolico o
"soft". Uno dei vantaggi dell'uso dell'opzione
-s
è che consente link
alle directory o a file di filesystem diversi.
La sintassi del comando è un po' ingannevole. Per esempio: ln -s vecchiofile nuovofile collega nuovofile, creato con l'istruzione, all'esistente vecchiofile.
Nel caso sia già presente un file di nome nuovofile, viene visualizzato un messaggio d'errore. |
Con i link si ha la possibilità di invocare uno stesso script (o qualsiasi altro eseguibile) con nomi differenti ottenendo un comportamento diverso in base al nome con cui è stato invocato.
Esempio 15-2. Ciao o arrivederci
#!/bin/bash # hello.sh: Visualizzare "ciao" o "arrivederci" #+ secondo le modalità di invocazione dello script. # Eseguiamo un collegamento allo script nella directory di lavoro corrente($PWD): # ln -s hello.sh goodbye # Ora proviamo ad invocare lo script in entrambi i modi: # ./hello.sh # ./goodbye CHIAMATA_CIAO=65 CHIAMATA_ARRIVEDERCI=66 if [ $0 = "./goodbye" ] then echo "Arrivederci!" # Se si desidera, qualche altro saluto dello stesso tipo. exit $CHIAMATA_ARRIVEDERCI fi echo "Ciao!" # Qualche altro comando appropriato. exit $CHIAMATA_CIAO |
Questi comandi danno accesso alle informazioni e alle pagine di manuale dei comandi di sistema e delle utility installate. Quando sono disponibili, le pagine info, di solito, contengono una descrizione più dettagliata che non le pagine di manuale.
[1] | Vengono chiamati dotfile quelli i cui nomi incominciano con un punto (dot), come ~/.Xdefaults, e che non vengono visualizzati con un semplice ls (sebbene ls -a ci riesca). Non possono neanche essere cancellati accidentalmente con un rm -rf *. I dotfile vengono solitamente usati come file di impostazione e configurazione nella directory home dell'utente. |