Esempi commentati di script per shell (v. 1.5)

Con la shell possiamo essere in grado di fare molte cose interessanti, spesso in modo più veloce che usando i con interfaccia grafica, e a volte nemmeno con quelli. Tutto ciò con un po’ di conoscenza dei principali comandi e dei modi per concatenarli tra di loro. Spesso basta una linea o due per risparmiare tempo e fare dei compiti che nemmeno ci verrebbe in mente di fare automaticamente.
Questa piccola raccolta di esempi commentati è intesa sia per risolvere dei problemi comuni che si possono presentare sia per dare un’idea delle tante cose che si possono fare ed essere di stimolo per farseli da soli…


Segnalo infine che in questa guida sempre dello stesso autore si trovano brevi illustrazioni sui comandi più comuni che può capitare di usare da shell, compresi esempi di uso elementari.

rpm -qa | grep -i | xargs rpm -ql | less
Volendo sapere per vari scopi cosa esattamente è stato istallato da un file .rpm, ma non ricordandosi precisamente il nome del pacchetto il sistema ci risponderebbe picche, quindi ecco la soluzione: dapprima interroghiamo tutta la lista dei pacchetti, poi estraiamo solo le righe con il pezzo del nome che ci ricordiamo, lo passiamo ancora a rpm tramite xargs (che non fa altro che prendere l’input dato e passarlo come ultimo parametro del comando che lo segue, in questo caso a “rpm -ql“) e infine per leggerlo più comodamente lo diamo a less.

ls -l *rpm | grep ‘Dec..4’ | awk ‘{print $9;}’ | xargs rpm -Uvh
Dopo aver scaricato una serie di pacchetti nella loro dir, li voglio istallare tutti quanti assieme perchè devono soddisffare delle dipendenze altrimenti darebbe errore. Faccio una lista dei file .rpm nella dir, li isolo con grep dal fatto che li ho presi il 4 dicembre, prendo il nono oggetto della riga con questo uso di “awk” e infine con xargs passo tutta la mia selezione di nomi di file a rpm per l’istallazione.

for a in *.jpg; do identify $a | grep 1024 | awk ‘{print $1;}’; done
Volendo sapere i nomi di immagini la cui dimensione è 1024, abbiamo impostato un ciclo “for” per cui per ogni file individuabile con “*.jpg” si compie l’azione chiusa tra “do” e “done“, e cioè si usa il comando “identify” che dà informzioni di natura grafica sul file (il cui nome via via viene rappresentato dalla variabile $a), quindi grep fa visualizzare solo le righe che contengono “1024” e infine awk divide la riga in parti spezzandola sugli spazi vuoti ” ” e ne mostra solo il primo pezzo. Il risultato sarà un elenco di nomi di file immagine con la caratteristica voluta.

for n in $(cat /etc/passwd | grep ‘.*home.*bash.*’ | tr “:” ” ” | awk ‘{print $1}’); do usermod -G fuse -a $n; done
Esempio tipico di comando da eseguire su una lista di “oggetti”, che in questo caso sono nomi di utenti. Con il costrutto for – do – done avendo cura di specificare cosa si vuole per lista. In questo caso usamo il costrutto $() che esegue il comando tra parentesi e lo passa come lista, un po’ come se facessi “for f in *jpg” passandogli i nomi di tutti i file jpg nella dir. La lista dei comandi dentro le parentesi con “cat” visualizza /etc/passwd, che contiene l’elenco degli utenti, “grep” la seleziona lasciando solo quelli che sono gli utenti reali (fanno login e hanno una home) e non quelli di sistema, “tr” sostituisce i due punti : con uno spazio su ogni riga, “awk” infine prende la prima parola che è appunto il nome utente. Infine ogni nome arriva a “usermod” che aggiunge l’utente al gruppo “fuse”.

for a in $(ll /media/disk/DCIM/11?_PANA/*JPG | grep ‘Apr 30’ | awk ‘{print $9}’); do cp -v $(ll $a | awk ‘{print $9}’) ./$(ll $a | awk -F ‘/’ ‘{print $6}’ | awk -F ‘.’ ‘{print $1}’).jpg; done;
Questa serie di comandi prende le foto da una scheda di memoria usb (/media/….) fatte in un determinato giorno (30 aprile) e le mette nella dir corrente con l’estensione cambiata da JPG a jpg. Per quanto possa sembrare complesso questo è solo un ciclo for – do con tre sottocatene di comandi annidate dentro le parentesi $(). La prima del for fa uscire la lista dei file, grep selezione quelli con la data voluta, awk prende il loro nome. Poi passa il nome completo al do che fa un cp dal nome originale a quello con l’estensione voluta, in pratica nel copiarli li rinomina. Interessante è il terzo $() che con i vari awk separa prima il nome dal percorso completo e poi anche dall’estensione, la quale viene rimessa jpg subito fuori dalla prantesi. “awk -F ”” serve proprio a dare un differente carattere di separazione (tra apici) invece dello spazio standard.

cd /home/maxmurd/gallery/$(ls -otr /home/www/BBC/gallery | tail -n1 | awk ‘{print $8}’)
Cosa fare se dobbiamo intervenire spesso sull’ultimo oggetto creato in una directory? Digitare il comando, poi il percorso e infine il nome del file?… Naah, possiamo fare di meglio. Esempio, avendo appena creato una sottodir dentro questa dir, come ci entriamo dentro subito? Ci facciamo dire da “ls -otr” l’elenco degli oggetti in ordine di data crescente, estrarre con “tail -n1” l’ultima riga, con “awk ‘{print $8}’” il nome della dir e infine mettiamo tutto dentro a $() e lo aggiungiamo al comando cd con il percorso, cosicchè il nome della dir-oggetto viene aggiunto a questo e in un attimo ci siamo dentro. Basta cambiare il comando iniziale e il percorso per avere a disposizione tante soluzioni differenti. Utile soprattutto in caso di directory in cui si opera spesso allo stesso modo, nomi lunghi e pigrizia… o anche se non si conosce il nome dell’oggetto.

grep -i |awk -F : ‘{print $1}’|xargs cat
Se scoprite che è contenuta dentro un solo file dei che avete specificato, e vi sentite troppo pigri per riscriverne il nome, basta selezionare il primo pezzo dell’output con “awk -F :…” dicendogli con “-F :” di prendere i : come carattere separatore, e poi passare tutto a cat tramite xargs. Forse ci metterete pure di più che a scrivere il nome del file con la tab completion di bash, ma almeno avrete usato il cervello per arrivarci…

Articoli correlati

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *