Visualizzazione post con etichetta Shell. Mostra tutti i post
Visualizzazione post con etichetta Shell. Mostra tutti i post

sabato 9 gennaio 2010

bash scripting - iterazione (p4)

Con questo post si concludono gli argomenti basilari per creare degli script in bash. Infatti vedremo come è possibile fare dei cicli d'iterazione.

In un ciclo è infatti possibile specificare di compiere determinate azioni finché non si verifica una determinata condizione.
In bash ci sono tre tipi di cicli:
  • while
  • until
  • for
While
Questo costrutto esegue le operazioni specificate finché la condizione specificata rimane vera, appena viene valutata falsa il ciclo termina ed il programma prosegue con l'istruzione successiva al while.
Esempio:

#! /bin/bash

contatore=0
while test  $contatore -lt 10 ; # condizione
do # inizio blocco istruzioni
    echo "Il contatore e' $contatore"
    let contatore=$contatore+1
done # fine blocco istruzioni

echo "Fine while"
exit 0

Il programma semplicemente stampa il valore di contatore finché questo è minore di 10.
L'istruzione let semplicemente assegna a contatore il valore della somma tra contatore ed 1.

Until
E' simile al while, ma con la differenza che il ciclo di istruzioni viene eseguito quando la condizione è valutata falsa, metre termina una volta che è vera.
Altra differenza fondamentale è che con until prima viene eseguito il blocco di istruzioni, poi viene fatto il controllo, mentre con while era l'opposto.
Esempio:

#!/bin/bash

contatore=10
until test $contatore -lt 0 ; #condizione
do # inizio blocco istruzioni
    echo "il contatore e' $contatore"
    let contatore=$contatore-1
done # fine blocco istruzioni

echo "Fine until"

exit 0

Il programma è simile al precedente, solo che contatore parte da 10 ed arriva a 0.

For
Il for è un costrutto che esegue le istruzioni specificate per una certa sequenza di valori. Ovvero viene usata una variabile che assume ad ogni iterazione il valore successivo (nella sequenza) a quello che aveva nell'iterazione precedente.
Vediamo il solito esempio con la sequenza di numeri da 0 a 10:

#!/bin/bash

for i in `seq 0 10`;
do # inizio blocco istruzioni
    echo "i= $i"
done # fine blocco istruzioni

echo "Fine for"
exit 0

Notiamo che i è la variabile che assume i valori della sequenza di numeri da 0 a 10 che è specificata con  `seq 0 10`.

Il for non si limita soltanto a sequenze di numeri, ma può essere usato per valori di qualsiasi tipo, come file o stringhe.
Esempio:

#!/bin/bash
for i in $( ls );
do
    echo File: $i
done
exit 0

In questo caso i conterrà tutti i file o directory restituite dal comando ls.

E questo è tutto!

martedì 5 gennaio 2010

bash scripting - if annidati e case (p3)

Prosecuzione naturale del post precedente non poteva essere nient'altro che una breve lezioncina sugli if annidati ed ovviamente il costrutto case.

Cosa sono gli if annidati?
Molto semplice: gli if annidati sono dei semplici if che contengono al loro interno (dopo la clausola then o else) degli altri if, che ovviamente possono avere anch'essi altri if all'interno.

Vediamo subito un esempio:

#! /bin/bash

# legge la scelta
echo "Scegliere la lingua: "
read lingua

if test $lingua = "italiano" # primo if
then
    echo "Ciao!"
    exit 0
else
    if test $lingua = "inglese" # if annidato
    then
        echo "Hello!"
        exit 0
    else
        echo "Non una lingua conosciuta"
        exit 1
    fi # chiude l'if annidato
fi #chiude il primo if

Come al solito il codice è banale: viene chiesto all'utente di inserire una lingua ed in base alla risposta viene stampato un messaggio di saluto.
Si può notare che priva viene controllato se la lingua è uguale ad "italiano", se si si stampa il messaggio e si esce, altrimenti si passa all'if successivo. Quindi si controlla se la lingua è uguale ad "inglese". Se anche questa non è vera verrà stampato un messaggio di errore e viene settato il valore d'uscita ad 1.

Ora, anche se costruire degli if annidati non è molto difficile, si nota subito che più il loro numero aumenta più il codice diventa illeggibile e ben presto faremo fatica a distinguere a quale if appartengono then/else e dove terminano i vari if.
Fortunatamente però abbiamo a disposizione la possibilità di usare il case!
Il case è semplicemente un altro modo di scrivere gli if annidati (o gli if in generale) con una sintassi molto meno complicata.
In poche parole si elencano i possibili valori che la variabile da controllare può assumere uno dopo l'altro.
Ovviamente il case funziona solo per controllare una sola variabile, quindi se nei nostri if annidati controlliamo più variabili non possiamo riscriverli con il case.
Vediamo un esempio:

#! /bin/bash

# legge la scelta
echo "Scegliere la lingua: "
read lingua

# inizio case
case $lingua in
    'italiano') # primo caso
        echo "Ciao!"
        exit 0
    ;; # fine primo caso
    'inglese') # secondo caso
        echo "Hello!"
        exit 0
    ;; # fine secondo caso
    'francese')
        echo "Bonjour!"
        exit 0
    ;;
    'tedesco')
        echo "Hallo!"
        exit 0
    ;;
    'spagnolo')
        echo "Hola!"
        exit 0
    ;;
    *) # caso di default
        echo "Non una lingua conosciuta"
        exit 1
    ;; # fine caso di default
esac # fine del case 

Come vedete lo script fa esattamente la stessa cosa del precedente (con l'aggiunta di qualche lingua in più).
Vediamo la sintassi:
  • case $lingua in--> identifica l'inizio del case con la variabile che verrà controllata.
  • 'italiano')--> è uno dei possibili casi che si possono verificare: le istruzioni che devono essere eseguite sono inserite dopo la parentesi tonda e ;; che chiudono il blocco di istruzioni per il caso
  • *)--> è il caso di default che viene eseguito quando nessuna delle altre condizione viene asserita. Di solito identifica un errore, come nell'esempio
  • esac--> chiude il costrutto case (come per if e fi è "simpaticamente" il contrario della parola che si usa per aprirlo)

sabato 2 gennaio 2010

bash scripting - if e test (p2)

Bene oggi vediamo come creare degli script più utili inserendo delle condizioni (o selezioni): il costrutto if.
In pratica if ci permette di eseguire un'azione o un'altra a seconda del verificarsi di una certa condizione. Ovviamente le azioni possono essere sia singole istruzioni che sequenze di istruzioni.

Vediamo meglio cosa significa con un po di buon pseudo-codice:

if condizione
then
    azione1
else
    azione2
fi

  • if ovviamente identifica il fatto che stiamo ponendo una condizione, mentre fi identifica il fatto che il costrutto if è terminato e lo script può continuare con quello che viene dopo.
  • condizione è una clausola che può assumere soltanto un valore booleano, ovvero può essere solo vera o falsa! Ad esempio se una variabile o l'output di un certo comando è uguale ad un valore specifico.
  • then identifica la parte di codice che verrà eseguita nel caso che condizione sia vera. Nell'esempio è azione1.
  • else invece identifica la parte di codice che viene eseguita nel caso condizione si verifichi falsa. Nell'esempio è azione2.
Dopo un poco di teoria vediamo un poco di pratica con un semplice script che dice se il numero inserito dall'utente e' positivo o no.
(ok, non è proprio un script utilissimo, ma serve come esempio)

#! /bin/bash

# chiede il numero all'utente e lo legge
echo "Inserisci numero"
read numero

# controlla se il numero e' maggiore di 0
if test $numero -gt 0
then
    echo "il numero $numero e' positivo"
else
    echo "il numero $numero non e' positivo"
fi

exit 0


La cosa che si nota subito è il fatto che con if viene usato anche il comando test.
test è un comando da terminale che viene usato per eseguire delle comparazioni tra variabili che possono essere: stringhe, interi o file.
La sintassi di test è abbastanza semplice, anche se ci sono un po di opzioni da ricordare.
La sintassi è: Valore opzione Valore
Dove valore può essere come detto prima una stringa, intero o file. (ovviamente devono essere entrambi dello stesso tipo)
Mentre opzione identifica il confronto da eseguire:
  • per stringhe: uguale (=) o diverso (!=)
  • per interi: uguale (-eq) maggiore o uguale (-ge) maggiore (-gt) minore o uguale (-le) minore (-lt) diverso (-ne)
  • per file: stesso device o inode number (-ef) più nuovo (-nt) più vecchi (-ot)
Per informazioni più dettagliate aprite un terminale e digitate man test

mercoledì 30 dicembre 2009

bash scripting - cos'è e perché (p1)

Iniziamo una mini guida sugli script bash, a cosa servono e perché dovremmo usarli?

Bash è l'acronimo di bourne again shell ed è l'interprete dei comandi che troviamo sulla maggior parte delle distribuzioni GNU/Linux, in pratica ciò che usate ogni volta che aprite il terminale ;-)
Per maggiori informazioni consultate il manuale.

Gli script invece sono dei semplici programmi che ci permettono automatizzare alcune operazioni inserendo dei dei comandi shell in sequenza per poi eseguirli al bisogno. Ovviamente abbiamo anche la possibilità di usare costrutti di selezione ed iterazione per rendere le cose ancora più interessante.

Ed ora vediamo un piccolo esempio di un semplice script:


 #! /bin/bash

# stampa a video
echo"Inserisci il tuo nome: "

# legge la risposta
read nome

# stampa un saluto
echo "Ciao $nome :-)"

exit 0

Ok, lo script è banale: chiede solo all'utente di inserire il suo nome e poi lo saluta stampando ancora il nome, però ci permette di osservare alcuni degli elementi basilari di uno script bash!
Quindi osserviamoli:
  • #! /bin/bash -> è l'interprete del nostro script, in questo caso abbiamo scelto bash, ma potrebbe essere anche il semplice sh o qualsiasi altro tipo di shell.
  •  commenti -> sono tutte quelle linee che iniziano con il carattere #. Questi servono soltanto per noi, come breve spiegazione di quello che avverrà nel nostro codice. L'interprete li salta semplicemente al momento dell'esecuzione, ma nonostante questo il consiglio è di utilizzarli SEMPRE!
  • echo -> è un comando che prende una stringa e la visualizza sull'output standard (il video). Una stringa è una serie di caratteri alfanumerici, è racchiusa tra le virgolette " ".
  • read -> è un comando che legge i caratteri che l'utente scrive sullo schermo fino alla pressione del tasto Invio. Poi prende tutto e lo mette in una variabile, nel nostro caso in nome. 
  • variabili -> una variabile in parole povere è un modo con cui si identifica un dato all'interno di un programma attraverso un nome. Il dato durante l'esecuzione può cambiare.
    In bash, a differenza di altri programmi, le variabili non sono tipizzate, quindi la stessa variabile durante l'esecuzione può arrivare a contenere stringhe, numeri, output di comandi, ecc. Importante notare anche che quando volgiamo riferirci ad una variabile per utilizzare il dato che contiene dobbiamo anteporre il simbolo $ al suo nome.
  •  exit -> è un comando per definire il valore d'uscita dello script. Se questo è 0 significa che lo script ha terminato la sua esecuzione in modo corretto. Tutti gli altri valori possono essere usati per identificare la presenza di un errore. Utilizzare exit può essere importante per quando useremo lo script in seguito.
Creazione dello script

Per creare uno script ci basta un editor di testo (come gedit, kate, emacs, ecc), scrivere le nostre istruzioni e salvarlo, possibilmente con un nome significativo.
Una volta fatto questo ci basterà dare allo script i permessi di esecuzione:

chmod +x nome_del_nostro_script

ed eseguirlo quando volgiamo

./nome_del_nostro_script

Con questo finisce la prima parte della nostra mini-guida.

sabato 3 ottobre 2009

Shell Expansion



Lo so vi state chiedendo che cavolo di titolo ho scelto! Adesso vi spiego:
Shell è il nome tecnico che si da al terminale di Unix (l'immagine a fianco).
Expansion invece possiamo definirle come quei trucchetti che ci possono semplificare di molto la vita quando diamo i comandi da terminale! Soprattutto se stiamo facendo cose piuttosto complesse.

Allora iniziamo dalla nostra cartella esempio che contiene i file:
esempio1.pdf esempio1.txt esempio2.pdf esempio2.txt pippo.pdf pippo.txt

Alcune expansion possono essere:
  • * → ci permette di dire alla nostra shell di "usare" i file che hanno qualsiasi carattere dopo quelli da noi specificati. Ad esempio se nella nostra cartella volessimo vedere i file che iniziano per es possiamo fare
    $ ls es* esempio1.pdf esempio1.txt esempio2.pdf esempio2.txt
  • ? → è simile al precedente solo che vale per un solo carattere del nome (?? per due, ??? per 3, ecc) Ad esempio
    $ ls esempio?.txt
    esempio1.txt esempio2.txt
  • [] → specificano un insieme di caratteri che devono essere presenti nel nome. Ad esempio ls esempio[1-4].txt
    esempio1.txt esempio2.txt

    (con il - specifichiamo che deve andare da ... a ... mentre senza sarebbe stato solo i due numeri [14] quindi solo esempio1.txt)
  • {} → anche questo simile al precedente solo che dice di usare soltanto le stringhe specificate tra le parentesi e separate da virgola. Ad esempio:
    $ ls esempio1.{txt,pdf}
    esempio1.pdf esempio1.txt

Ovviamente tutti questi possono essere combinati per ottenere cose molto interessanti!

Altre "scorciatoie" utili possono essere :
  • ~ → (Alt Gr + ì) che identifica la vostra home (/home/tuo_nome)
  • . → che identifica la directory corrente
  • .. → che identifica la directory padre (se siamo in /home/nostro_nome la directory padre è /home)
  • il tasto tab → che se premuto mentre digitiamo il nome di una directory o file lo completa automaticamente (se non ci sono nomi troppo simili)
 Spero di esservi stato utile! Se conoscete altri "trucchetti" che mi sono sfuggiti aspetto i vostri consigli e commenti ;)