Guida al bash-scripting
4 partecipanti
Pagina 1 di 1
Guida al bash-scripting
Spesso si dichiara la potenza della console di Linux; molto più spesso chi lo dice parla per sentito dire e non ne capisce il motivo.
Qualunque funzione del sistema può essere eseguita da console, dalla creazione di file, alla gestione del kernel, il download, la compilazione di sorgenti ecc.
Insomma, Linux *è* la console, tutto il resto è una semplice interfaccia per la comodità dell'utente (e far bella figura con gli amici).
Il bash-scripting è il linguaggio di gestione dei comandi di Linux, cioè uno script gestisce una catena di comandi tramite le funzioni tipiche dei linguaggi di programmazione.
In questa guida analizzeremo proprio il bash-scripting in sè, omettendo la parte riguardante tutti i comandi di Linux e di ogni applicazione utilizzata negli script stessi.
SCRIVERE SCRIPT IN BASH
#!/bin/bash
Questa qui sopra è l'intestazione di uno script che dice a Linux quale applicazione eseguirà lo script stesso, cioè la console /bin/bash
(notare la somiglianza con altri linguaggi nati da Bash...)
Dopo aver scritto il nostro script potremo salvarlo con estensione .sh oppure senza estensione; rendendo eseguibile lo script, ed eventualmente posizionandolo in qualche path di sistema, sarà possibile richiamarlo semplicemente scrivendo in console il nome del file.
Per ora prendetelo per buono, vedremo tutto più avanti...
HELLO WORLD
Iniziamo con il solito programma: aprite l'editor di testo e scrivete
Potrete salvare il file come "pippo.sh" oppure come "pippo" nella vostra /home, per eseguirlo sarà sufficiente scrivere a console "bash pippo" oppure "bash pippo.sh".
Possiamo anche rendere eseguibile lo script tramite il comando:
$ chmod 755 pippo
(755 lettura, scrittura, esecuzione al proprietario; lettura e esecuzione a gruppo e altri)
in questo modo il nostro script sarà eseguibile con questo comando:
$ ./pippo
Ora lo script risulta eseguibile; che succede se lo inseriamo in un path di sistema? I path di sistema sono visualizzabili tramite il comando "echo $PATH", che restituirà ad esempio il valore /usr/local/bin. Vediamo un po' che succede:
# cp pippo /usr/local/bin
dopo la copiatura come eseguiremo pippo?
$ pippo
e otterremo la nostra stringa "Hello World!". Come vedete abbiamo creato un comando di Linux!
Certo direte voi, bella forza...vero, andiamo un po' più a fondo:
VARIABILI E FUNZIONI
Una variabile è una locazione di memoria riservata ad un certo dato; bash utilizza fondamentalmente due sistemi di assegnazione: o il dato viene dichiarato direttamente, oppure viene memorizzato tramite richiesta all'utente.
L'assegnazione di variabile avviene senza alcun simbolo particolare, per venire richiamata il nome andrà preceduto dal carattere "$":
flotaman@debian:~$ bash prova_bash
Chi ha scritto questo script inutile?
floatman
Questo script scemo che scrive "Hello World!" e' scritto da floatman...
flotaman@debian:~$
Come vedete "STRINGA" è una variabile inserita da noi, mentre "AUTORE" è una seconda variabile che viene richiesta all'utente.
Il simbolo "\" mi permette di scrivere le virgolette, che altrimenti verrebbero ignorate.
L'utilizzo delle lettere maiuscole per le variabili è una prassi ma non è necessaria, ovviamente per UNIX dopo aver scritto "STRINGA" non sarà possibile richiamarla come "$stringa" ma solo utilizzando lettere maiuscole. In questo caso ho utilizzato due stringhe di testo, ovviamente è possibile utilizzare anche numeri o comandi Linux in maniera da gestirne l'output...ma questa è un'altra storia.
CONTROLLO DI FLUSSO
Il controllo di flusso comprende l'insieme delle funzioni logiche utilizzate da un script.
Per dichiarare una funzione utilizziamo questa dicitura:
function nome_funzione
{
argomenti...
}
Utilizzare una funzione ci permette di richiamarla più volte nel corso di uno stesso script.
L'argomento può comprendere sia elementi "echo", sia ovviamente strumenti di controllo come le classiche funzioni dei vari linguaggi.
IF
La funzione IF in bash assume tre costrutti:
# comandi eseguiti se condizione è vera
if condizione ; then
comandi
fi
# comandi_1 eseguiti se la condizione è vera, oppure comandi_2 se è falsa
if condizione ; then
comandi_1
else
comandi_2
fi
# comandi_1 se condizione_1 è vera, comandi_2 se condizione_1 è falsa *e condizione_2 è vera*
if condizione_1 ; then
comandi_1
elif condizione_2
comandi_2
fi
Nelle condizioni possono essere inseriti i veri operatori matematici (+, - ecc.) e logici (=, != ecc.)
Un esempio semplicissimo e utilissimo, da imparare a memoria, è il seguente:
Ogni utente ha un id identificativo univoco; per sapere l'id del vostro utente basta dare da terminale il comando "id -u" che fornisce l'id dell'utente corrente.
Se vi chiedessi qual'è l'id di root cosa rispondereste? Ovviamente sarà "0" (non stavate pensando "1" vero?)
Allora guardate un po' se vi piace questo:
All'inizio ho posto le variabili esterne alla funzione, poi "verifica_root" va a vedere se ho i permessi di root per eseguire lo script.
Le parentesi [] delimitano la condizione che è appunto "id utente diverso da 0"; qualora lo script non venga eseguito come root otteremo il messaggio di echo della funzione; "exit 0" ci fa tornare alla console per eseguire nuovamente lo script.
Solo le ultime tre righe sono il flusso vero e proprio del programma.
In questo caso abbiamo utilizzato il valore "!=" in quanto ben conosciuto, a complicarci la vita esistono altri parametri che qui non verranno spiegati per intero.
Una delle cose più potenti di bash per regolare le funzioni condizionali è il "test". Questo gestisce le condizioni del flusso sia in base agli operatori logici e matematici, sia in base a particolari opzioni tipiche di bash:
Un esempio tipico di utilizzo è rappresentato dal file .bash_profile esistente nella /home di ogni utente, tale file regola le opzioni utente di esecuzione di bash. Aprendo .bash_profile troverete questo:
Seconda regola: se esiste la directory (-d) /home/user/bin, inseriscila tra i path di sistema.
Vediamo qualche altro test importante oltre -f e -d (lista completa con il comando "help test"...buona fortuna):
[-r, -w, -x] nome_file => vero se nome_file è [leggibile, scrivibile, eseguibile] da parte dell'utente.
Nelle applicazioni grafiche gestisce alert box e salvataggio file
file_1 [-nt, -ot] file_2 => vero se file_1 è [più nuovo, più vecchio] di file_2
La base dei gestori aggiornamenti (apt-get, yum, emerge...)
[-z, -n] stringa => vero se stringa è [zero (=vuota), non zero]
Gestisce valori nulli o informazioni supplementari
Qualcuno avrà notato che ancora non ho parlato di operazioni matematiche...ora possiamo farlo per scrivere un utile esempio.
Iniziamo dalle basi, ritornando su qualcosa visto in precedenza e aggiungiamo qualcosa di nuovo e utile:
Come si vede read può prendere delle opzioni, "-t num_secondi" imposta un tempo in secondi di prosecuzione dello script qualora non venga inserito alcun valore. Un'altra importante opzione è -s che impadisce la visualizzazione dei caratteri digitati, ad esempio password.
L'utilizzo degli operatori matematici credo non richieda alcun commento esclusa la gestione del modulo, cioè il resto di una divisione.
"if [ $((CIFRA_2 % 2)) -eq 0 ]" quindi "se il resto di (CIFRA_2 : 2) è uguale a 0" la funzione risponde vero e il numero è pari, altrimenti è dispari.
Alla fine della funzione, lo script esce a console con "exit 0", se questo fosse omesso il programma continuerebbe e produrrebbe un errore.
Da notare come i valori inseriti all'interno delle operazioni matematiche non utilizzino il simbolo "$", che viene invece riportato per indicare l'operazione stessa.
Per concludere possiamo dire che if supporta ovviamente l'annidamento per gestire più opzioni:
CASE
Subito al sodo:
$HOME è un path speciale che indica la /home dell'utente (avremmo anche pututo scrivere /home/$USER/mp3)
Il simbolo "*" indica ovviamente tutti i file di quell'estensione, nell'ultimo caso indica "tutti gli altri valori di $numero"
Da notare l'uso di ";;" in tutti i casi escluso quello di uscita, oltre a "esac" a fine funzione.
Un uso interessante e utile di case è l'opzione di scelta yes/no che ritroviamo in molti programmi per Linux:
Il simbolo "|" inplica un OR, cioè raggruppa le due opzioni per evitare errori di capitalizzazione delle lettere usate.
LOOPING
Per chi non lo sapesse, il looping è l'esecuzione ripetuta di una serie di istruzioni in base a determinate condizioni.
Bash gestisce il looping tramite tre istruzioni: "while", "until", "for"
Le prime due le considereremo insieme perchè rappresentano le due facce della stessa medaglia:
Nel primo caso leggiamo "somma 1 a $numero *finchè* è minore o uguale a 100"; cioè prosegue l'azione finchè la condizione risulta vera.
Nel secondo caso avremo "somma 1 al numero *finchè non* è maggiore di 100"; prosegue l'azione finchè la condizione risulta non vera.
Un utilizzo molto interessante di questi looping è la gestione di demoni senza impostare l'avvio automatico, ad esempio il demone di Tor.
Tor e Privoxy sono programmi di navigazione anonima, l'installazione attiva due demoni in avvio automatico dentro /etc/init.d; i comandi che possiamo dare nel caso non si desideri l'avvio automatico sono "start", "restart" e "stop" da terminale (come root) ogni volta che vogliamo utilizzare Tor. Vediamo quindi se possiamo semplificarci la vita:
Come vedete la variabile "opzione" è settata in un valore nullo, valore che poi si modifica nel corso della procedura.
I più bravi lettori avranno notato che potevamo anche inserire due funzioni vere e proprie: una per il controllo dei permessi di root e una con quest'ultimo esempio.
FOR
Il ciclo for ha la seguente struttura:
for "variabile" in "valori"; do
"comando"
done
La forma non è amichevole, comunque "variabile" sarà un elemento di una serie di "valori"; finchè "variabile" non sarà individuata all'interno di tutti i "valori" verrà eseguito "comando".
Nonostante la mia pessima spiegazione un esempio ci chiarirà meglio le idee...
Il comando "cat" preleva un elemento in input (un file) per elaborarlo in uno script; il comando "wc" permette una serie di conteggi dei valori all'interno dei file, ad esempio l'opzione -c conta i byte e può quindi essere utilizzata per contare i caratteri usati:
CONCLUSIONI
Qui si conclude la nostra visita introduttiva dentro Bash; come ho già spiegato la complesità deriva dal notevole numero di funzioni e opzioni presenti nei vari comandi.
Ovviamente ogni programma utilizzabile da console può essere inserito in uno script.
Per finire, qualche consiglio per vivere felici:
Innanzitutto le solite buone regole della programmazione: ordine nel codice, commenti, debugging
Per quanto Bash possa venire assimilato ad un linguaggio semplice per Linux da parte dei neofiti, fate sempre molta attenzione.
Con bash si possono andare a toccare impostazioni di sistema ad un livello estremamente profondo, evitate le prove nubbe "perchè tanto è come DOS" e se lavorate su cose delicate utilizzate cd-live per i test. Eviterete sia danni sia eventuale sporcizia di sistema.
[ve l'ho detto, poi non venite a piangere...]
La possibilità di ottenere codice sorgente amplifica enormemente gli spazi di utilizzo di bash, che comunque resta l'anello di interazione tra sistema e utente qualunque linguaggio si utilizzi per creare programmi (bash richiama file in C, script in Perl ecc.).
Imparate a cercare e lavorare sui sorgenti facendo attenzione alle licenze (su cui ho già qualcosa in preparazione...)
Buon divertimento!
Qualunque funzione del sistema può essere eseguita da console, dalla creazione di file, alla gestione del kernel, il download, la compilazione di sorgenti ecc.
Insomma, Linux *è* la console, tutto il resto è una semplice interfaccia per la comodità dell'utente (e far bella figura con gli amici).
Il bash-scripting è il linguaggio di gestione dei comandi di Linux, cioè uno script gestisce una catena di comandi tramite le funzioni tipiche dei linguaggi di programmazione.
In questa guida analizzeremo proprio il bash-scripting in sè, omettendo la parte riguardante tutti i comandi di Linux e di ogni applicazione utilizzata negli script stessi.
SCRIVERE SCRIPT IN BASH
#!/bin/bash
Questa qui sopra è l'intestazione di uno script che dice a Linux quale applicazione eseguirà lo script stesso, cioè la console /bin/bash
(notare la somiglianza con altri linguaggi nati da Bash...)
Dopo aver scritto il nostro script potremo salvarlo con estensione .sh oppure senza estensione; rendendo eseguibile lo script, ed eventualmente posizionandolo in qualche path di sistema, sarà possibile richiamarlo semplicemente scrivendo in console il nome del file.
Per ora prendetelo per buono, vedremo tutto più avanti...
HELLO WORLD
Iniziamo con il solito programma: aprite l'editor di testo e scrivete
- Codice:
#!/bin/bash
# il mio primo script
echo "Hello World!"
Potrete salvare il file come "pippo.sh" oppure come "pippo" nella vostra /home, per eseguirlo sarà sufficiente scrivere a console "bash pippo" oppure "bash pippo.sh".
Possiamo anche rendere eseguibile lo script tramite il comando:
$ chmod 755 pippo
(755 lettura, scrittura, esecuzione al proprietario; lettura e esecuzione a gruppo e altri)
in questo modo il nostro script sarà eseguibile con questo comando:
$ ./pippo
Ora lo script risulta eseguibile; che succede se lo inseriamo in un path di sistema? I path di sistema sono visualizzabili tramite il comando "echo $PATH", che restituirà ad esempio il valore /usr/local/bin. Vediamo un po' che succede:
# cp pippo /usr/local/bin
dopo la copiatura come eseguiremo pippo?
$ pippo
e otterremo la nostra stringa "Hello World!". Come vedete abbiamo creato un comando di Linux!
Certo direte voi, bella forza...vero, andiamo un po' più a fondo:
VARIABILI E FUNZIONI
Una variabile è una locazione di memoria riservata ad un certo dato; bash utilizza fondamentalmente due sistemi di assegnazione: o il dato viene dichiarato direttamente, oppure viene memorizzato tramite richiesta all'utente.
L'assegnazione di variabile avviene senza alcun simbolo particolare, per venire richiamata il nome andrà preceduto dal carattere "$":
- Codice:
#!/bin/bash
STRINGA="Hello World!"
echo "Chi ha scritto questo script inutile?"
read AUTORE
echo "Questo script scemo che scrive \"$STRINGA\" e' scritto da $AUTORE..."
flotaman@debian:~$ bash prova_bash
Chi ha scritto questo script inutile?
floatman
Questo script scemo che scrive "Hello World!" e' scritto da floatman...
flotaman@debian:~$
Come vedete "STRINGA" è una variabile inserita da noi, mentre "AUTORE" è una seconda variabile che viene richiesta all'utente.
Il simbolo "\" mi permette di scrivere le virgolette, che altrimenti verrebbero ignorate.
L'utilizzo delle lettere maiuscole per le variabili è una prassi ma non è necessaria, ovviamente per UNIX dopo aver scritto "STRINGA" non sarà possibile richiamarla come "$stringa" ma solo utilizzando lettere maiuscole. In questo caso ho utilizzato due stringhe di testo, ovviamente è possibile utilizzare anche numeri o comandi Linux in maniera da gestirne l'output...ma questa è un'altra storia.
CONTROLLO DI FLUSSO
Il controllo di flusso comprende l'insieme delle funzioni logiche utilizzate da un script.
Per dichiarare una funzione utilizziamo questa dicitura:
function nome_funzione
{
argomenti...
}
Utilizzare una funzione ci permette di richiamarla più volte nel corso di uno stesso script.
L'argomento può comprendere sia elementi "echo", sia ovviamente strumenti di controllo come le classiche funzioni dei vari linguaggi.
IF
La funzione IF in bash assume tre costrutti:
# comandi eseguiti se condizione è vera
if condizione ; then
comandi
fi
# comandi_1 eseguiti se la condizione è vera, oppure comandi_2 se è falsa
if condizione ; then
comandi_1
else
comandi_2
fi
# comandi_1 se condizione_1 è vera, comandi_2 se condizione_1 è falsa *e condizione_2 è vera*
if condizione_1 ; then
comandi_1
elif condizione_2
comandi_2
fi
Nelle condizioni possono essere inseriti i veri operatori matematici (+, - ecc.) e logici (=, != ecc.)
Un esempio semplicissimo e utilissimo, da imparare a memoria, è il seguente:
Ogni utente ha un id identificativo univoco; per sapere l'id del vostro utente basta dare da terminale il comando "id -u" che fornisce l'id dell'utente corrente.
Se vi chiedessi qual'è l'id di root cosa rispondereste? Ovviamente sarà "0" (non stavate pensando "1" vero?)
Allora guardate un po' se vi piace questo:
- Codice:
#!/bin/bash
STRINGA="Hello World!"
function verifica_root
{
if [ $(id -u) != "0" ]; then
echo "Devi essere root anche per scrivere \"$STRINGA\" !"
echo "Benvenuto su Linux..."
exit 0
fi
}
function hello_world
{
echo "Hello World!"
}
verifica_root
hello_world
exit 0
All'inizio ho posto le variabili esterne alla funzione, poi "verifica_root" va a vedere se ho i permessi di root per eseguire lo script.
Le parentesi [] delimitano la condizione che è appunto "id utente diverso da 0"; qualora lo script non venga eseguito come root otteremo il messaggio di echo della funzione; "exit 0" ci fa tornare alla console per eseguire nuovamente lo script.
Solo le ultime tre righe sono il flusso vero e proprio del programma.
In questo caso abbiamo utilizzato il valore "!=" in quanto ben conosciuto, a complicarci la vita esistono altri parametri che qui non verranno spiegati per intero.
Una delle cose più potenti di bash per regolare le funzioni condizionali è il "test". Questo gestisce le condizioni del flusso sia in base agli operatori logici e matematici, sia in base a particolari opzioni tipiche di bash:
Un esempio tipico di utilizzo è rappresentato dal file .bash_profile esistente nella /home di ogni utente, tale file regola le opzioni utente di esecuzione di bash. Aprendo .bash_profile troverete questo:
- Codice:
# prima regola
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# seconda regola
if [ -d ~/bin ] ; then
PATH=~/bin:"${PATH}"
fi
Seconda regola: se esiste la directory (-d) /home/user/bin, inseriscila tra i path di sistema.
Vediamo qualche altro test importante oltre -f e -d (lista completa con il comando "help test"...buona fortuna):
[-r, -w, -x] nome_file => vero se nome_file è [leggibile, scrivibile, eseguibile] da parte dell'utente.
Nelle applicazioni grafiche gestisce alert box e salvataggio file
file_1 [-nt, -ot] file_2 => vero se file_1 è [più nuovo, più vecchio] di file_2
La base dei gestori aggiornamenti (apt-get, yum, emerge...)
[-z, -n] stringa => vero se stringa è [zero (=vuota), non zero]
Gestisce valori nulli o informazioni supplementari
Qualcuno avrà notato che ancora non ho parlato di operazioni matematiche...ora possiamo farlo per scrivere un utile esempio.
Iniziamo dalle basi, ritornando su qualcosa visto in precedenza e aggiungiamo qualcosa di nuovo e utile:
- Codice:
#!bin/bash
# inserisco le variabili
CIFRA_1=4
# inserisco le funzioni
function digita_presto
{
echo "inserisci velocemente il secondo addendo da sommare a $CIFRA_1:"
if read -t 4 CIFRA_2; then
echo "Bravo! Hai fatto presto a scrivere $CIFRA_2"
else
echo "Ho scritto \"inserisci velocemente\" oppure no?"
exit 0
fi
}
function operazioni_numeri
{
echo "$CIFRA_1 + $CIFRA_2 = $((CIFRA_1 + CIFRA_2))"
echo "$CIFRA_1 - $CIFRA_2 = $((CIFRA_1 - CIFRA_2))"
echo "$CIFRA_1 * $CIFRA_2 = $((CIFRA_1 * CIFRA_2))"
echo "$CIFRA_1 : $CIFRA_2 = $((CIFRA_1 / CIFRA_2))"
echo "Modulo di $CIFRA_1 : $CIFRA_2 = $((CIFRA_1 % CIFRA_2))"
}
function pari_dispari
{
if [ $((CIFRA_2 % 2)) -eq 0 ]; then
echo "Il numero inserito e' pari"
else
echo "Il numero inserito e' dispari"
fi
}
# flusso vero e proprio del programma
digita_presto
operazioni_numeri
pari_dispari
exit 0
Come si vede read può prendere delle opzioni, "-t num_secondi" imposta un tempo in secondi di prosecuzione dello script qualora non venga inserito alcun valore. Un'altra importante opzione è -s che impadisce la visualizzazione dei caratteri digitati, ad esempio password.
L'utilizzo degli operatori matematici credo non richieda alcun commento esclusa la gestione del modulo, cioè il resto di una divisione.
"if [ $((CIFRA_2 % 2)) -eq 0 ]" quindi "se il resto di (CIFRA_2 : 2) è uguale a 0" la funzione risponde vero e il numero è pari, altrimenti è dispari.
Alla fine della funzione, lo script esce a console con "exit 0", se questo fosse omesso il programma continuerebbe e produrrebbe un errore.
Da notare come i valori inseriti all'interno delle operazioni matematiche non utilizzino il simbolo "$", che viene invece riportato per indicare l'operazione stessa.
Per concludere possiamo dire che if supporta ovviamente l'annidamento per gestire più opzioni:
- Codice:
#!/bin/bash
echo "Inserisci un numero tra 1 e 3 (estremi inclusi)"
read numero
if [ "$numero" = "1" ]; then
echo "hai scritto 1"
else
if [ "$numero" = "2" ]; then
echo "hai inserito 2"
else
if [ "$numero" = "3" ]; then
echo "hai inserito 3"
else
echo "Ho detto un numero tra 1 e 3 !"
fi
fi
fi
CASE
Subito al sodo:
- Codice:
#!/bin/bash
echo "Questo programma mette ordine nella /home."
echo
echo " 1 - ordina tutti i file .mp3 dentro /mp3"
echo " 2 - ordina le foto .jpg dentro /foto"
echo " 3 - mette tutti i .wmv porno dentro /parrocchia"
echo
echo "Scegli cosa ordinare:"
read numero
case $numero in
1 ) mkdir $HOME/mp3
mv *.mp3 $HOME/mp3
;;
2 ) mkdir $HOME/foto
mv *.jpg $HOME/foto
;;
3 ) mkdir $HOME/parrocchia
mv *.wmv $HOME/parrocchia
echo "mi fai veramente schifo! Che dice tua moglie?"
;;
* ) echo "Ma possibile che su *tre* numeri riesci a sbagliare?"
esac
exit 0
;;
$HOME è un path speciale che indica la /home dell'utente (avremmo anche pututo scrivere /home/$USER/mp3)
Il simbolo "*" indica ovviamente tutti i file di quell'estensione, nell'ultimo caso indica "tutti gli altri valori di $numero"
Da notare l'uso di ";;" in tutti i casi escluso quello di uscita, oltre a "esac" a fine funzione.
Un uso interessante e utile di case è l'opzione di scelta yes/no che ritroviamo in molti programmi per Linux:
- Codice:
#!/bin/bash
echo "Questo programma nasconde a tua moglie tutti i tuoi pornetti .wmv"
echo "tutti i file saranno spostati nella directory /parrocchia"
echo -n "Vuoi proseguire (lurido pornomane)? [S/n]: "
read risp_segaiolo
case $risp_segaiolo in
s | S ) mkdir $HOME/parrocchia
mv *.wmv $HOME/parrocchia
echo "mi fai veramente schifo! Che dice tua moglie?"
;;
n | N ) echo "Meglio! Spero che tua moglie ti inXXXi!"
;;
* ) echo "Hey, Pippa-man! S oppure N, o sei gia' diventato cieco?"
esac
exit 0
;;
Il simbolo "|" inplica un OR, cioè raggruppa le due opzioni per evitare errori di capitalizzazione delle lettere usate.
LOOPING
Per chi non lo sapesse, il looping è l'esecuzione ripetuta di una serie di istruzioni in base a determinate condizioni.
Bash gestisce il looping tramite tre istruzioni: "while", "until", "for"
Le prime due le considereremo insieme perchè rappresentano le due facce della stessa medaglia:
- Codice:
#!/bin/bash
# looping con WHILE
numero=0
while [ $numero -le 100 ]; do
echo "$numero"
numero=$((numero + 1))
done
# ----------------------------------
#!/bin/bash
# looping con UNTIL
numero=0
until [ $numero -gt 100 ]; do
echo "$numero"
numero=$((numero + 1))
done
Nel primo caso leggiamo "somma 1 a $numero *finchè* è minore o uguale a 100"; cioè prosegue l'azione finchè la condizione risulta vera.
Nel secondo caso avremo "somma 1 al numero *finchè non* è maggiore di 100"; prosegue l'azione finchè la condizione risulta non vera.
Un utilizzo molto interessante di questi looping è la gestione di demoni senza impostare l'avvio automatico, ad esempio il demone di Tor.
Tor e Privoxy sono programmi di navigazione anonima, l'installazione attiva due demoni in avvio automatico dentro /etc/init.d; i comandi che possiamo dare nel caso non si desideri l'avvio automatico sono "start", "restart" e "stop" da terminale (come root) ogni volta che vogliamo utilizzare Tor. Vediamo quindi se possiamo semplificarci la vita:
- Codice:
#!/bin/bash
opzione=
until [ "$opzione" = "x | X" ]; do
echo "GESTIONE TOR/PRIVOXY"
echo
echo "S - Avvia Tor"
echo "C - Chiudi Tor"
echo "R - Riavvia Tor"
echo
echo "X - Esci"
echo
echo -n "Opzione: "
read opzione
case $opzione in
s | S ) /etc/init.d/tor start
/etc/init.d/privoxy start
echo "Tor avviato..."
echo
;;
c | C ) /etc/init.d/tor stop
/etc/init.d/privoxy stop
echo "Tor disattivato"
echo
;;
r | R ) /etc/init.d/tor restart
/etc/init.d/privoxy restart
echo "Tor riavviato"
echo
;;
x | X ) exit 0
;;
* ) echo "Inserisci S, C o X..."
echo
esac
done
exit 0
;;
Come vedete la variabile "opzione" è settata in un valore nullo, valore che poi si modifica nel corso della procedura.
I più bravi lettori avranno notato che potevamo anche inserire due funzioni vere e proprie: una per il controllo dei permessi di root e una con quest'ultimo esempio.
FOR
Il ciclo for ha la seguente struttura:
for "variabile" in "valori"; do
"comando"
done
La forma non è amichevole, comunque "variabile" sarà un elemento di una serie di "valori"; finchè "variabile" non sarà individuata all'interno di tutti i "valori" verrà eseguito "comando".
Nonostante la mia pessima spiegazione un esempio ci chiarirà meglio le idee...
Il comando "cat" preleva un elemento in input (un file) per elaborarlo in uno script; il comando "wc" permette una serie di conteggi dei valori all'interno dei file, ad esempio l'opzione -c conta i byte e può quindi essere utilizzata per contare i caratteri usati:
- Codice:
#!/bin/bash
function scegli_file
{
echo "Inserisci il percorso del file di testo da usare:"
read file_scelto
}
function conta_lettere
{
conteggio=0
for i in $(cat $file_scelto); do
conteggio=$((conteggio + 1))
echo "La parola $conteggio ($i) ha $(echo -n $i | wc -c) caratteri"
done
}
scegli_file
conta_lettere
exit 0
CONCLUSIONI
Qui si conclude la nostra visita introduttiva dentro Bash; come ho già spiegato la complesità deriva dal notevole numero di funzioni e opzioni presenti nei vari comandi.
Ovviamente ogni programma utilizzabile da console può essere inserito in uno script.
Per finire, qualche consiglio per vivere felici:
Innanzitutto le solite buone regole della programmazione: ordine nel codice, commenti, debugging
Per quanto Bash possa venire assimilato ad un linguaggio semplice per Linux da parte dei neofiti, fate sempre molta attenzione.
Con bash si possono andare a toccare impostazioni di sistema ad un livello estremamente profondo, evitate le prove nubbe "perchè tanto è come DOS" e se lavorate su cose delicate utilizzate cd-live per i test. Eviterete sia danni sia eventuale sporcizia di sistema.
[ve l'ho detto, poi non venite a piangere...]
La possibilità di ottenere codice sorgente amplifica enormemente gli spazi di utilizzo di bash, che comunque resta l'anello di interazione tra sistema e utente qualunque linguaggio si utilizzi per creare programmi (bash richiama file in C, script in Perl ecc.).
Imparate a cercare e lavorare sui sorgenti facendo attenzione alle licenze (su cui ho già qualcosa in preparazione...)
Buon divertimento!
Re: Guida al bash-scripting
Sì, qualcosina di carino lo voglio tenere
Tra l'altro in questi giorni sto su Windows, quindi mi è difficile produrre qualcosa
Tra l'altro in questi giorni sto su Windows, quindi mi è difficile produrre qualcosa
Re: Guida al bash-scripting
Ho appena finito di leggere la guida.
È fatta molto bene, complimenti, cerca di approfondire un po' di più se hai tempo.
È fatta molto bene, complimenti, cerca di approfondire un po' di più se hai tempo.
Re: Guida al bash-scripting
Grazie ^^
È deisamente elementare però credo di aver fatto un buon riassunto per chi vuole iniziare....sono stato un bel po' a faròa tra l'altro xD
È deisamente elementare però credo di aver fatto un buon riassunto per chi vuole iniziare....sono stato un bel po' a faròa tra l'altro xD
Argomenti simili
» [bash] Contare le pagine totali dei pdf in una cartella
» [Bash] Visualizzare proprio IP
» [Bash] Quotazioni azionarie
» [Bash] Update sistema Debian
» [bash] Da flv a mp3 (tutti i file di una directory)
» [Bash] Visualizzare proprio IP
» [Bash] Quotazioni azionarie
» [Bash] Update sistema Debian
» [bash] Da flv a mp3 (tutti i file di una directory)
Pagina 1 di 1
Permessi in questa sezione del forum:
Non puoi rispondere agli argomenti in questo forum.