Sc rip ti n g
Mi ch ela ng elo D ilig en ti In ge gn eri a I nfo rma tica e de ll'I nfo rma zi on e dil ig mi c@ dii .u nisi .it
So m m ar io Lin gu ag gi di Scri pti ng Ba sh Pe rl Pyt ho n
Sc rip ti n g
●
Lin gu ag gi di scri pti ng so no in te rp re ta ti
Si esegue il programma interpretando ed eseguendo un'istruzione alla volta
Programma che interpreta il programma passo passo viene detto interprete
I linguaggi compilati come il C/C++ costruiscono un binario in linguaggio macchina
Binario viene eseguito direttamente
Linguaggi compilati sono in generale più lenti dei linguaggi compilati
Sc rip ti n g Lin gu ag gi di scri pti ng p erme tto no d i co nn ett ere tra di lo ro p iù e se cu zi on i d i p ro gra mmi co mp ila ti
Sono tipicamente usate per la realizzazione di pipeline complesse
Tuttavia moderni linguaggi di scripting vanno ben oltrequesta semplice funzione
Perl e Python ad esempio permettono la scrittura di programmi arbitrariamente complessi
Supportano costrutti che permettono scrittura di codice in larga scala anche se sempre pagano una penalità come prestazioni
Sono linguaggi di alto livello che permettono di realizzare cose complesse con sintassi semplice
Sc rip ti n g
●
D oma nd a l eci ta d a p orsi
Il C/C++ è linguaggio formale completo: permette direalizzare qualsiasi algoritmo
Perché mai usare un altro linguaggio?
●
R isp ost a
È per definizione possibile realizzare tutto inlinguaggio compilato di basso livello
Linguaggi di scripting sono, in genere, non-tipati epermettono alta velocità di sviluppo se usati nell'ambito giusto
Sc rip ti n g Ta nti lin gu ag gi di scri pti ng so no n ati n eg li u ltimi a nn i
Bash: ha sintassi contorta ma ottima integrazione con UNIX e facile gestire files
Perl: completo e con molte librerie, molto usato per text processing
Sintassi porta ad una difficile gestione di progetti complessi
Python: linguaggio di scripting a classi, il più moderno e con codice gestibile anche per progetti grandi
Sviluppo meno veloce per cose semplici rispetto a Bash/Perl
Molto completo, ad esempio ha supporto per multithreading
PHP: unisce caratteristiche di vari linguaggi,usatissimo in ambito Web per implementare CGI
Buona integrazione con SQL e database
Viene di solito studiato a Reti di Calcolatori
Bash
●Ba sh è l'i nte rp re te d ei co ma nd i ch e vi en e co mu ne me nte u sa to n ei si st emi U N IX
Quello che esegue i comandi che digitate sul prompt
Creato nel 1989 per migliorare Bourne-shell (sh), l'interprete precedente
●
U no scri pt ba sh è in si eme d i co ma di ch e p otre st e dig ita re su lla lin ea d i co ma nd o
Assolutamente identico eseguire script o copiare uno alla volta le righe sul terminale
B as h : u ti lizzi ti p ic i
Mo lto u sa to d a a mmi nist ra to ri d i si st ema F on da me nta le p er Si te R eli ab ilit y En gin ee rs ch e ge st isco no le ma cch in e d i u n d ata ce nte r F on da me nta le a nch e p er ge st ire pipelines : se qu en za d i p ro gra mmi (sp esso in C /C ++) da ese gu ire U tile p er cre are u tili ty scri pt p er a ttivi tà ri pe tu te su un a ma cch in a N on u sa rlo p er pro gra mmi ch e e se gu on o mo lte op era zi on i a ritme tich e! Le nto +si nta ssi n on a de gu ata
Bash
●In g en ere u no scri pt ba sh si sa lva su fil e co n po st fisso .sh
Non obbligatorio, talvolta il postfisso è omesso
●
Ese mp io
script.sh
●
Si e se gu e d ig ita nd o
bash script.sh●
Ese mp io
echo ls > script.shbash script.sh echo è comando print,stampa la stringa successiva> ridireziona l'uscita del comandoecho sul file script.sh che vienecreato
Bash Po ssi bil e n oti fica re q ua le in te rp re te d eve es eguir e i co ma nd i d ire tta me nte su lla p rima ri ga d el file st esso
#! path_ad_interprete_bashIn U N IX pe r ve de re d ove si tro va l'i nte rp re te d ig ita te
which bash
In genere è in /bin/bash
In tal caso la prima riga del file script.sh sarà#! /bin/bash
Per marcare il file come eseguibile digitatechmod +x script.sh
Ora per eseguire lo script basta un semplicescript.sh
Bash
●C omme nti so no lin ee ch e i nizi an o p er #
●
C ome a bb ia mo vi st o l e p rima ri ga è u n'e cce zi on e
Qualsiasi altra riga che inizia per #, non viene interpretata
Bash ech o st amp a su llo sch ermo Al cu ni ca ra tte ri h an no si gn ifica to sp eci ale (l o ve dre mo ), a d e se mp io $ ,”, {, }, (, )
Se volete riferirvi al carattere, e non al suo specialesignificato dovete prependerlo con backslash \
Esempioecho lsecho “ls”echo \”l\”\$
Se \ precede ritorno a capo, la riga successiva fa parte del comando della riga precedente. Permette di spezzare comandi complessi su più righe
B as h : va ria b ili
●
N ome ch e i nizi a p er $ i nd ica u na va ria bil e
l'interprete sostituisce $nome con il valore della variabile
$nome equivale a digitare ${nome}, preferibile il secondo per evitare confusione
●
Po ssi bil e d efi nire n uo ve va ria bil i co n i l co ma nd o
nome=valoreEsempiodata=20110103echo \$data=${data}
●
$ si u sa p er rife rire la va ria bil e ma n on p er de fin irl a
B as h : va ria b ili
D IF F ER EN Z A F O N D AMEN TAL E T R A BASH E C /C ++
I linguaggi C++ o Java sono tipati, ogni variabile che viene definita ha un tipo
In bash ed altri linguaggi di scripting il tipo non èesplicitamente definito ma inferito dal contesto
Questo permette una velocità di sviluppo molto più alta
Lo svantaggio è il minore controllo semantico che fa l'interprete
Facile che si creino bug che il compilatore non cattura
B as h : va ria b ili
●
I ti pi so no d efi nit i d al co nte st o
data=”201103”data=201103 Stringa è tra “”NumeroB as h : va ria b ili e q u o te s
G li a pici d op pi “” de fin isco no u na st rin ga I ri fe rime nti a va ria bil i d en tro “” so no ri so lti da ll'in te rp re te Ese mp io
DAY=10MONTH=3DATA=”data is ${DAY}/${MONTH}”echo ${DATA}
B as h : va ria b ili e q u o te s
●
G li a pici si ng oli '' de fin isco no u na st rin ga
●
I ri fe rime nti a va ria bil i d en tro '' non so no riso lti da ll'in te rp re te
●
Ese mp io
DAY=10MONTH=3DATA='data is ${DAY}/${MONTH}'DATA=”data is ${DAY}/${MONTH}”echo ${DATA}
B as h : va ria b ili p re d efi n ite
Al cu ne va ria bil i so no p re de fin ite se nza ch e l 'u te nte le sp eci fich i Ad e se mp io
$USER o ${USER} indica il nome dell'utente attuale
${SHELL} indica l'interprete usato attualmenteecho “${USER} $SHELL”
${HOME} indica la home directory dell'utente che esegue lo script
B as h : ex it
●
Po ssi bil e u sci re d a scri pt co n i l co ma nd o
exitPer definire il valore ritornato dalla scriptexit NUM
Esempio se tutto andato a buon fineexit 0
B as h : es ec u zi o n e b in ar i
Pe r ese gu ire u n b in ari o co mp ila to ch ia ma to “co ma nd o” co n a rg ome nti “a b c” ba st a l a l in ea
comando a b c
Come se lo chiamaste dal terminale
In g en ere si me tte u n co ma nd o p er rig a
Possibile mettere più comandi per riga separati da ;
Esempioecho “pippo”vostro_programma argomentiecho “ciao”; echo “riciao”; ls
B as h : if
●
D ive rsi mo di di scri ve re u n i f
if condizione ; then comando1; comando2; ... ; fi●
O pp ure
if condizionethencomando1comando2...fiB as h : if els e
O pp ure p ossi bil e scri ve re if else
if condizione1 ; then comando1 comando2elif condizione2 ; then comando3else comando4 comando5fiB as h : co n d izi o n i
●
So no in dica te tra [[ … ]]
●
Ese mp io
DATE=2011if [[ $DATE == 2011 ]]; then echo SI; else echo NO; fiif [[ $DATE > 2008 ]]; then echo NI; else NO; fi
C o n tr o llo ri u sc ita p ro g ra m m i
●
La va ria bil e sp eci ale $ ? me mo rizza il va lo re rito rn ato d all 'u ltimo co ma nd o e se gu ito
Se 0 tutto andato bene, altrimenti possibile prendere provvedimenti
●
U sa nd o $ ? i n i f … th en … fi p ossi bil e co ntro lla re la ri usci ta d i p ip eli ne d i p ro gra mmi
C o n tr o llo ri u sc ita p ro g ra m m i
ls file_che_non_esisteif [[ $? == 0 ]]; then echo ls ha funzionatoelse echo ls ha fallito exit 1fi
C o n tr o llo ri u sc ita p ro g ra m m i
CMD=”programma1 argomenti1”$CMDif [[ $? == 0 ]]; then echo $CMD = OKelse echo $CMD = FAILED exit 1fiCMD=”programma2 argomenti2”$CMDif [[ $? == 0 ]]; then echo $CMD = OKelse echo $CMD = FAILED exit 1fi Comando eseguito
Comando eseguito
Pipeline interrotta appenaun programma fallisce.Stampa errore
B as h : co n d izi o n i
●
Pe r te st are l'e si st en za d i u n f ile o se u na va ria bil e è vu ota si u sa no i t est
●
Ese mp io
DATE=2011DATA=””if [[ -n $DATE ]]; then echo NONVUOTA; else echo VUOTA; fiif [[ -n $DATA ]]; then echo NONVUOTA; else echo VUOTA; fi
B as h : co n d izi o n i d i te st
Ecco u na list a d i co nd izi on i d i te st u sa bil i tra [[ … ]]
-l string length of the string-n string true iff length of string is nonzero-z string true iff length of string is zero-d file true iff name is a dir.-f file true iff name is not a dir.-p file true iff name is a pipe-s file true iff file is non empty-r file true iff file is readable-w file true iff file is writeable-x file true iff file is executableB as h : fo r
●
C icl i fo r so no scri vi bil i in mo lti mo di
for i in {1..N}; do echo $idone●
op pu re
for i in 0 1 5 d f 6 1; do echo $idone●
op pu re
for (( c=1; c<=5; c++ )); do echo $cdoneB as h : & &
Po ssi bil e e se gu ire co ma nd i in se qu en za se pa ra ti d a && Il co ma nd o su cce ssi vo e se gu ito so lo se il pre ce de nte h a a vu to su cce sso Ese mp io
ls file_che_non_esiste && echo OKls file_che_esiste && echo OK
B as h : co m an d i u ti li
●
V i so no ta nti co ma nd i f on da me nta li d i cu i i mp ara re l'u tili zzo , q ue st a è u na list a d i p och i co ma nd i
Filtri: grep
Conteggio: wc
Tokenizzatore: cut
Linguaggio di programmazione: awk
Manipolazione: sed
Gestione File: pwd,ls,mv,cp,rm,mkdir
Visualizzazione File: cat, less
●
Pe r ave re in fo rma zi on i su u n co ma nd o d ig ita re
man comando
B as h : vis u ali zza zi o n e e fi ltr o fi le
ca t n ome file : vi su ali zza l'i nte ro co nte nu to d i u n f ile su llo sch ermo le ss n ome file : co me il p re ce de nte ma d ivi de la vi su ali zza zi on e i n p ag ine de lla dim en si on e d ello sch ermo gre p [ op zi on i] e sp re ssi on e f ile : fi ltra le lin ee d i u n f ile
le linee che rispettano l'espressione sono stampate
Ha varie opzioni utili, esempio -v stampa le linee che non rispettano l'espressione
Esempio: stampare le linee che contengono “pippo”
grep pippo nomefile
B as h : g es ti o n e fi le s o d ire cto ry
●
mv [p ath 1/] file so rg en te [p ath 2/] file de st in azi on e
muove o rinomina un file
●
mv [p ath 1/] file so rg en te 1 [ pa th 2/] file so rg en te 2 … dire ct ory_ de st in azi on e
muove un insieme di files in directory destinazione
●
cp [o pzi on i] [ pa th 1/] file so rg en te [p ath 2/] file de st in azi on e
copia un file
opzione -r copia ricorsivamente contenuto di unadirectory
B as h : g es ti o n e fi le s o d ire cto ry
rm [o pzi on e] [p ath 1/] file
rimuove un file
opzione -r permette la rimozione ricorsiva di unadirectory ed il suo contenuto
pwd
ritorna la directory corrente
B as h : g es ti o n e fi le s o d ire cto ry
●
ch mo d [ sp eci fich e] file
Cambia i permessi di accesso ad un file
Specifiche hanno il formato[ugo]{+,-}[rwx]
r=read, w=write, x=esecuzione
+ aggiunge il permesso, - lo toglie
u=permesso_per_utente_stesso, g=permesso_per_utenti_con_stesso_gruppo_di_utente,o=permesso_per_gli_altri
Esempiochmod ugo+xr nomefile
Aggiunge permessi di lettura ed esecuzione a tutti per nomefile
B as h : g es ti o n e fi le s
mkd ir [p ath /]n ome dire ct ory
crea directory
ls [o pzi on i] [ pa th /]
mostra il contenuto di una directory
se path omesso, mostra contenuto directory corrente
opzione -l mostra anche le informazioni sui files
opzione -a mostra files nascosti (in unix sono files che iniziano per .)
B as h : es p an sio n e fi le s
●
Ba sh h a su pp ort o i nte gra to p er le e sp re ssi on i re go la ri
* match per qualsiasi stringa
? match per qualsiasi carattere
[set_caratteri] match per un carattere del set
●
Esp re ssi on e co n t ali ca ra tte ri vi en e e sp an sa n ell a list a d i fi le co n ma tch
Bash sostituisce la lista direttamente nel comando
B as h : es p an sio n e fi le s
Ese mp i
ls *.txtstampa i file con estensione .txt
mv [abc]*.txt dest
muove i files che iniziano per a o b o c con estensione .txt in directory dest
for i in *.txt; do grep pippo $i > $i.pippodone
Per ogni file .txt stampa in file.pippo le linee che contengono la stringa pippo
B as h : co m p re ss io n e
●
C omp re ssi on e i n L in ux in g en ere co n g zi p
gzip file1 … fileNgenera file1.gz … fileN.gz
Esempiogzip *.txt # compressione di tutti i file .txt
●
D eco mp re ssi on e co n g un zi p
gunzip file1.gz … fileN.gzricrea file1 … fileN
Esempiogunzip *.txt.gz
B as h : cr ea zi o n e a rc h iv i d i fi le s
C oma nd o t ar pe r cre are a rch ivi (co mp rime a nch e)
tar cvfz nomearchivio.tar.gz file1 … fileNEsempiotar cvfz files_di_testo.tar.gz *.txt
Possibile anche creare archivio di intere directories
Esempio: archiviare i files/directory che iniziano per 'a'tar cvfz archivio.tar.gz a*
Pe r rie sp an de re u n a rch ivi o
tar xvfz nomearchivio.tar.gzB as h : ss h
●
Po ssi bil e a pri re u n t ermi na le su u na ma cch in a re mo ta co n i l co ma nd o ssh
sshutente@url [comando]
In genere viene richiesta una password
Se il comando viene specificato, non si apre un terminale ma semplicemente si esegue il comando sulla macchina remota
Esempissh sandro@lucy.dii.unisi.itssh sandro@lucy.dii.unisi.it “rm pippo.txt”
B as h : sc p
scp p er co pia re /le gg ere fil e d a/a ma cch in a re mo ta
Copia file locale su macchina remotascp file utente@url:destinazione
Copia file remoto in localescp utente@url:path/files destinazione
'.' indica directory corrente. In genere corrisponde a home per macchina remota e directory attuale in locale
Esempiscp sandro@lucy.dii.unisi.it:dir/pippo.txt .scp pippo.txt sandro@lucy.dii.unisi.it:.scp *.txt sandro@lucy.dii.unisi.it:dir
B as h : rs yn c
●Permette di syncronizzare due directory, anche su computer diversi
Copia il contenuto da una directory sorgente ad una destinazione
Utile per fare backups: ne vedremo un esempio di utilizzo
B as h : p ip es
●
Pe rme tto no d i co nca te na re co ma nd i
L'uscita di un comando è fornita in input al comando successivo senza dover salvare il contenuto su file
Sintassi
comando1 | comando2 | … | comandoN
Meccanismo efficiente ed elegante, fondamentale in scripting bash
B as h : to ke n izza zi o n e
●
cu t p erme tte d i p re nd ere u no sp eci fico to ke n di un a va ria bil e. Ese mp io
Opzione -d permette di specificare un separatoreusato per dividere in tokens una stringa
Opzione -f permette di dire quali campi della string vogliamo
-fN ritorna l'N-esimo token
-fN-M ritorna dall'N-esimo all'M-esimo token
Esempioecho “file.txt” | cut -f1 -d'.'
fornisce il nome del file esclusa l'estensione
B as h : co n te g g i e m o d ifi ch e
w c no me file : co nta n ume ro p aro le , ca ra tte ri e lin ee
Se usato in pipes permette cose comegrep pippo file | wc
conta il numero di righe di file che contengono pippo
se d e sp re ssi on e n ome file : ma nip ola u n f ile
espressione può essere qualsiasi espressione regolare
Opzione -i modifica il file al volo
Esempio, rimuove spazi multiplised 's/ \+/ /' file > file1sed -i 's/ \+/ /' file # come prima ma sul file stesso
B as h : $() o ``
●
Ba sh p erme tte d i in se rire u n co ma nd o a ll'in te rn o d i un a ltro
$(comando) o `comando` eseguono comando esostituiscono l'uscita dello stesso
Esempio per cambiare l'estensione ad un file
SRG=nome.txtDST=$(echo $SRG | cut -f1 -d.).datmv $SRG $DST
B as h : $() o ``
Ese mp io p er ca mb ia re l'e st en si on e d i t utt i i fil e i n un a d ire ct ory
for SRG in $(ls); do DST=$(echo $SRG | cut -f1 -d.).dat mv $SRG $DSTdone
B as h : re d ire cti o n
●
Po ssi bil e i nvi are l'u sci ta d i u n co ma nd o o b in ari o su file
Per inviare lo stdout su filecomando > file
Per inviare lo stderrcomando 2> file
Per inviare lo stderr e stdoutcomando 2>&1 > file
B as h : Es em p io
Su pp on ia mo a bb ia te d ue p ro gra mmi in C ++
Il primo chiamato matrix_mult, moltiplica due matrici lette da file stampa il risultato sullo stdout
Il secondo chiamato matrix_mult_scalar prende il risultato del precedente e moltiplica la matrice peruno scalare
Realizzare uno script bash che esegue i due comandi in sequenza
Se il primo comando fallisce il secondo non viene eseguito
Se uno dei due comandi fallisce la pipeline ritorna un codice dierrore
B as h : Es em p io #! /b in /b ash # Pa sso 1 ma tri x_ mu lt f ile _ma tri ce 1 f ile _ma tri ce 2 > ou tp ut # Pa sso 2 if [ [ $ ? == 0 ] ]; t he n ma tri x_ mu lt_ sca la r ou tp ut 4.3 > ou tp ut_ fin ale fi exi t $ ?
B as h : fu n zi o n i
Po ssi bil e cre are fu nzi on i
function nomefunzione { … }Se so no p assa ti a rg ome nti a lla fu nzi on e, $1 mo mo rizza il pri mo , $ 2 i l se co nd o, ecc. Pe r ch ia ma re u na fu nzi on e
nomefunzione arg1 arg2 …A T T EN Z IO N E: le va ria bil i d efi nit e i n u na fu nzi on e so no g lo ba li. N on co me in C /C ++
Per definire una variabile locale va specificata locallocal VAR=5
B as h : fu n zi o n i
●
$# d en tro u na fu nzi on e ri to rn a i l n ume ro d i arg ome nti p assa ti a lla st essa
●
$@ ri to rn a u na st rin ga ch e co nca te na tu tti gli arg ome nti
B as h : fu n zi o n i e se m p io
function die { echo $1; exit 1}function CheckLastRunCommand { local -r cmd="$1" if [[ $? != 0 ]]; then die "Last command died: $cmd" fi}function Run { local -r cmd="$1" local -r ofile="$2" echo $cmd \> $ofile $cmd > $ofile CheckLastRunCommand $cmd}
B as h : es em p io c o n fu n zi o n i #! /b in /b ash # Pa sso 1 R un “ma tri x_ mu lt f ile _ma tri ce 1 f ile _ma tri ce 2” ou tp ut # Pa sso 2 R un “ma tri x_ mu lt_ sca la r ou tp ut 4.3 ” ou tp ut_ fin ale exi t 0
Avendo messo l'arg tra “”, tuttotra “” va in $1 dentro la funzione.Altrimenti sarebbe successo che$1=matrix_mult_scalar$2=outputecc.B as h : o p zi o n i d a p ro m p t
C ome in fu nzi on i p ossi bil e p assa re a rg ome nti d a lin ea d i co ma nd o a d u no scri pt
$1 per il primo argomento
$2 il secondo e così via
Con test -n $i possibile testare se argomento vienespecificato
Esempioif [[ -n $1 ]]; then echo Primo argomento: $1; fiif [[ -n $2 ]]; then echo Secondo argomento: $2; fiif [[ -n $3 ]]; then echo Terzo argomento: $3; fi
B as h : o p zi o n i d a p ro m p t
●
$# fo rn isce il nu me ro d i p ara me tri p assa ti d a l in ea d i co ma nd o
●
$@ co nca te na tu tti gli a rg ome nti
●
ge to pts pe rme tte d i le gg ere o pzi on i cl assi ch e i n fo rma -l ett era (e se mp io -d o -g va lo re )
Vediamone un esempio di utilizzo
B as h : g eto p ts
U sa w hil e/d o ch e n on a bb ia mo vi st o (n on si u sa qu asi ma i)
while getopts "d:p:un" flag; do case $flag in d ) FLAGS_d="$OPTARG";; p ) FLAGS_p="$OPTARG";; u ) FLAGS_u=1;; n ) FLAGS_n=1; * ) exit 0;; esacdone Lista opzioni, se lettera seguita da ':',opzione seguita da un valore.Se opzione seguita da ':” la variabile$OPTARG ne memorizza il valore
In questo esempio la seguentelinea di comando è validascript.sh -d 1 -p ciao -u
Non valida invece (-p ha valore)script.sh -d 1 -p
B as h : es em p io s cr ip t p er b ac ku p s
#! /bin/bashGFLAGS=0; REMOTE_SH="ssh"FLAGS_d=0 # If true a dryrun is performedFLAGS_p="$HOME/Documents,$HOME/src"FLAGS_u="sandro" # Remote userFLAGS_m="10.1.0.73" # Remote machineFLAGS_r="backup/latest" # Remote pathwhile getopts "d:p:u:m:r:" flag; do case $flag in d ) FLAGS_d="$OPTARG";; p ) FLAGS_p="$OPTARG";; u ) FLAGS_u="$OPTARG";; m ) FLAGS_m="$OPTARG";; r ) FLAGS_r="$OPTARG";; * ) exit 0;; esac done...
B as h : es em p io c o m p le to
…REMOTE_CMP="${FLAGS_u}@${FLAGS_m}"OPT=""if [[ ${FLAGS_d} == 1 ]]; then OPT="$OPT --dry-run"fifor i in $(echo ${FLAGS_p} | tr ',' ' '); do CMD="rsync $OPT -t -p -e $REMOTE_SH -avz $i \ ${REMOTE_CMP}:${FLAGS_r}" echo $CMD $CMDdoneexit 0