31.05.2013 Views

Bash scripting - Lordhack.altervista.org - Altervista

Bash scripting - Lordhack.altervista.org - Altervista

Bash scripting - Lordhack.altervista.org - Altervista

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Ciao a tutti,<br />

non ho niente da fare così un corsetto vi voglio fare (per questa rima merito la morte lo sò )<br />

Allora vi siete mai chiesti su cosa si basa il nostro caro vecchio unix/linux? Bhè la risposta è "lo shell<br />

script"<br />

Lo shell script è un VERO E PROPRIO linguaggio di programmazzione ed è forse l'unica cosa che<br />

riesce ad accomunare tutti gli unix!!! Infatti su uno unix di anni fa provate a lanciare uno script<br />

configure scoprirete che funziona a dovere!!!<br />

Bene per cominciare voglio dirvi come ho fatto a imparare io.<br />

"man bash"


significato speciale del carattere dopo. per esempio<br />

nome\ di\ file<br />

non verrà interpretato separatamente in quanto la \ rimuove il significato speciale dello spazio e il<br />

programma interpreta le tre parole come un solo argomento.<br />

A echo non frega molto del numero di argomenti in quanto fa cmq il suo lavoro ma è bene sapere<br />

queste cose.<br />

Torniamo all'ultima istruzione<br />

Codice:<br />

exit 0<br />

Questa istruzione fa uscire dal programma e ritorna come codice di errore 0. Quando un programma<br />

ritorna un codice di 0 di conseguenza l'OS pensa che non ci siano stati errori.<br />

Note e Variabili<br />

Le note in shell script si fanno con un<br />

#<br />

tutto ciò che c'è dopo il # non viene considerato<br />

Al contrario del c e ogni altro linguaggio di programmazzione di basso livello le varibili possono<br />

contenere di tutti. Numeri, stringe, dati vari ecc. ecc.<br />

Per creare una varibile il codice è:<br />

Codice:<br />

varibile= "un testo a caso" # crea una varibile<br />

Mi raccomando di non distaccare mai l' = dal nome della varibile.<br />

Per riusare una variabile fate così:<br />

Codice:<br />

variabile= "un testo a caso" # crea una varibile<br />

echo $variabile # scriverà : un testo a caso<br />

echo "$variabile e un altro # scriverà : un testo a caso e un altro<br />

Se cercate di usare un varibile non inizializzata o comunque inesistente questa varibile conterrà "".<br />

Questa a mio avviso non è molto bello inquanto se ci fosse un messaggio tipo in c (undefined<br />

reference) sarebbe possibile capire se vi sono errori di battitura ($facia invece di $faccia)... Cmq<br />

ognuno ha le sue opinioni...<br />

Aritmetica<br />

L'aritmetica in shell script è un pò strana cmq cominciamo con il fare un esempio<br />

Codice:


echo 1+1<br />

Cosa vi aspettate da questo? forse che scriva 2? NO! scriverà "1+1". Per fargli scrivere 2 dovrete<br />

sostituire l'1+1 con $(1+1) adesso farà la somma da questo facciamo un pò di esempi<br />

Codice:<br />

echo $(1+1) # scrive 2 (somma)<br />

echo $(1­1) # scrive 0 (sottrazzione)<br />

echo $(1*1) # scrive 1 (moltiplicazione)<br />

echo $(1/1) # scrive 1 (divisione)<br />

factor 15 # scrive 15: 3 5 ( 15 scomposto in fattori primi :P )<br />

I/O (input / output)<br />

Per leggere qualcosa da tastiera usate read Questo scriverà dentro quello che<br />

arriva da tastiera.<br />

Per scrivere a schermo usate echo. E' il + semplice e il + funzionante. Adesso spieghiamo meglio nella<br />

prossima sezione.<br />

stdout e stdin<br />

3 file virtuali per ogni programma eseguito... Questo è il fondamento di unix... Probabilmente molti di<br />

voi che leggete questo articolo già conoscete la filosofia "all is a file" comunque per dovere di cronaca<br />

la rispiegherà in poche righe.<br />

Sotto unix TUTTO viene trattato come un file... Dagli HD ai socket internet. TUTTO viene letto e<br />

scritto come fosse un file. Per fare un esempio quando voi scrivete qualcosa su terminale in modo<br />

trasparete scrivete su un file chiamato stdout.<br />

Ogni programma eseguito ha a disposizone 3 file (virtuali) Stdout (Standard Output), Stdin (Standard<br />

Input) e Stderr (Standard Error). A seconda delle esigenza linux questi file corrispondo a una cosa o a<br />

un'altra. Quando usate un FrontEnd (ark per esempio) il programma grafico passa i dati al programma<br />

testuale tramite stdin. Questo è assolutamente uguale a digitare i comandi da tastiera.<br />

Tornando allo Shell Script se dovete scrivere in un file potete usare un semplice:<br />

Codice:<br />

echo "foooooooooo" > nomefile<br />

In questo modo "foooooooooooo" verrà scritto non + su terminale ma all'interno di nomefile.<br />

">" dice all'interprete di comandi che lo stdout del programma deve finire da qualche parte diversa dal<br />

normale. Allo stesso modo se volete che il programma riceva lo stdin da un file potete scrivere "<<br />

nomefile" in questo modo il programma penserà che voi sulla tastiera stiate digitando il contenuto di


nomefile.<br />

Il programma in ogni caso non ha modo di acc<strong>org</strong>ersi che il suo stdout o stdin è stato cambiato.<br />

Ora se qualcuno di voi ha provato a mandare il terminale di DOOM3 su un file mi chiederà<br />

"Perchè doom3 si blocca se reindirizzo il suo stdout? Come fa ad acc<strong>org</strong>ersene?"<br />

Semplice, il problema lo fa la shell... non Doom3<br />

Ricapitolando:<br />

Codice:<br />

if<br />

> file # invia lo stdout del prog a file<br />

< file # invia file come stdin del prog<br />

Data la complessità dell'if dello shell script è giusto dedicargli un paragrafo intero.<br />

IF è ls struttura di controllo più amata da tutti i programmatori. In shell script il suo funzionamento di<br />

base è molto semplice<br />

Codice:<br />

#Sintassi dell'if<br />

if condizione ; then<br />

codice<br />

elif codice<br />

fi<br />

Per "codice" si intende una serie di istruzioni shell script.<br />

if esegue le istruzioni contenute tra then e elif/fi se condizione ritorna 0. Condizione è un comanda<br />

shell che viene eseguito in un terminale a parte se il codice di errore di questo è 0 (nessun errore)<br />

allora if esegue le istruzioni. Se il codice di errore è diverso da 0 if salta al prossimo elif o esce se<br />

incontra un fi.<br />

elif è un abbreviazione di else if e permette di eseguire un altro controllo. elif non ha bisogno di essere<br />

chiuso esso viene infatti chiuso dal fi dell'if principale o da un altro elif.<br />

fi termina l' if (come "}" del c o endif del basic.)<br />

Da questo facciamo un esempio per farvi capire meglio.<br />

Codice:


#!/bin/sh<br />

#questo codice controlla se esiste un file.<br />

if test ./file ; then<br />

echo file esiste<br />

elif test ./file2 ; then<br />

echo file2 esiste<br />

elif test ./file3 ; then<br />

echo file3 esiste<br />

else<br />

echo nessun file che io conosca<br />

fi<br />

Test è un'istruzione base della shell onnipresente che permette di controllare l'esistenza di un file. Con<br />

alcune opzioni test può anche dire se si tratta di file eseguibili, di testo ecc ecc.<br />

Tornando al funzionamento dello script praticamente questo script controlla se esiste file o file2 o file3.<br />

Se trova uno dei 3 dice che esiste Se non trova nessuno dei 3 dice che non ce ne è nessuno che conosca.<br />

In seguito riprenderemo questo script e lo miglioreremo con dei cicli. Ovviamente esiste il modo di<br />

confrontare anche stringhe. Facciamo us esempio.<br />

Codice:<br />

#!/bin/sh<br />

#Confronto di stringhe<br />

echo "Ciao come ti chiami?"<br />

read NOME<br />

if [ "$NOME" = "snake88" ]; then<br />

echo "Salve mio creatore"<br />

elif [ "$NOME" = "" ]; then<br />

echo "Perchè non mi hai detto come ti chiami?"<br />

else<br />

echo "$NOME 6 brutto! :­P"<br />

fi<br />

Quando usate [ ] significa che state facendo un confronto. Esistono vari operatori di confronto...<br />

= Uguaglianza<br />

== "<br />

!= Differente.


Esistono anche operatori aritmetici ma sinceramente non li ho mai usati...<br />

Cicli<br />

Eccoci alla parte più colorita del corso. I cicli. Tutti coloro che hanno programmato avranno usato un<br />

for o un while in tutte le loro versioni e sintassi. Bene visto che lo shell script E' un linguaggio di<br />

programmazzione li abbiamo anche qui!!!<br />

Io trovo i cicli della shell complicati da capire soprattutto per chi viene dal C come me ma comunque<br />

una volta afferrato il primo tipo sarà facile capire gli altri.<br />

Per cominciare bisogna dire che in sh non ci basiamo su numeri per i cicli (possiamo anche farlo!!!) ma<br />

su un numero di elementi!. Il primo esempio che vi faccio è proprio basato sui numeri.<br />

Codice:<br />

#!/bin/bash<br />

for i in seq 1 10;<br />

do<br />

echo $i<br />

done<br />

in questo esempio cose succede? Allora per prima cose viene eseguito "seq 1 10". seq è un programma<br />

che prende 2 numeri e scrive su stdout la sequenza di numeri per esempio<br />

seq 1 10 scrive<br />

1<br />

2<br />

3<br />

[...]<br />

9<br />

10<br />

A questo punto abbiamo 10 elementi per cui il nostro for farà 10 cicli. All'interno di $i verrà a ogni cicli<br />

inserito il valore di seq in quel ciclo per cui:<br />

ciclo 1 $i = 1<br />

ciclo 2 $i = 2<br />

[...]<br />

ciclo 10 $i = 10<br />

do e done sono rispettivamente inizio e fine delle istruzioni da eseguire nel ciclo.<br />

detto questo vediamo se indovinate che output avrà questo programma<br />

Adesso passiamo a qualcosa di un pò più complicato. Facciamo un rinominatore di file.<br />

Il seguente programma chiede all'utente un prefisso poi esegue un rinomino in ordine alfabetico.


Codice:<br />

#!/bin/sh<br />

#Un rinominatore di file by Snake88<br />

echo "Inserire il prefisso per i file"<br />

read PREFIX<br />

$n = 1<br />

for i in ls;<br />

do<br />

mv $i $PREFIX$n<br />

$n = $($n+1)<br />

done<br />

Questo script prende tutti i file nella direcotory attuale e li rinomina con il prefisso da voi inserito e un<br />

numero. Ma vediamo il funzionamente Step by step<br />

1. echo "Inserire il prefisso per i file" # scrive cosa vuole<br />

2. read PREFIX # Legge da tastiera<br />

3. $n = 1 # mette n a 1<br />

4. for i in ls;<br />

Questa istruzione esegue ls quindi esegue il ciclo per un numero di elementi pari agli elementi retituiti<br />

da ls. A ogni ciclo l'elemento restituito da ls corrispondente al ciclo viene copiato in i<br />

5. do # inizio ciclo<br />

6. mv $i $PREFIX$n # Sposta il file $i in $PREFIX e $n (numero progressivo)<br />

7. $n = $($n+1) #incrementa $n di uno con l'artmetica precedentemente usata.<br />

8. done # dice al for " Con $i ho finito puoi cambiarla" Quindi il for inserisce il nuovo valore in $i e<br />

torna a "do"<br />

Bhè ragazzi penso proprio di avervi insegnato tutto ciò di cui avete bisogno per avvicinarvi a questo<br />

linguaggio orientato alla compatibilità...<br />

Buon divertimento e ricordate che se volete informazioni su un'istruzione sarà sufficente un<br />

man <br />

e avrete un buon HELP!<br />

Se non vi dispiace vorrei ricevere qualche feedback.<br />

_________________<br />

Questo è tutto.... Per ora!<br />

Snake88<br />

Guida scaricata da lordhack.<strong>altervista</strong>.<strong>org</strong>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!