PERL
 Cos’e’ PERL ?
 PracticalExtraction and Report Language
oppure
 Pathological Eclectic Rubbish Lister
?
 Nato per assistere l’utente Unix per le comuni operazioni, troppo pesanti, troppo dipendenti dalla shell ma troppo
complesse da codificare in C ...
 Linguaggio Interpretato con sintassi C-like, con elementi di C, Fortran, Basic, Pascal, Shell etc etc.
Accetta la maggior parte dei comandi Unix. Accetta comandi sed e awk ...
 Ottimizzato per eleborare testi, ma anche per gestire numeri
 Correntemente molto usato per operazioni di amministrazione di sistema
 Scritto da Larry Wall (“A shell for C programmers”)
 Distribuito gratuitamente ( !)
 PERL scripts :
 Commenti => carattere #
 Informazione sul programma =>
 Le istruzioni sono seguite da “ ;”
Sulla prima riga # !/user/bin/perl
1
Tipi di dati in PERL
 Dati scalari, array, array associativi
 Numeri : rappresentazione interna solo doppia precisione
 Assegnazione : floating point, integer, stringhe C-like
 Delimitatori delle stringhe :
 accento singolo : per avere un carattere ‘ => \’
 accento doppio : il backslash consente di inserire caratteri di controllo
Caratteri di controllo :
\n
\r
\t
\f
\b
\v
\a
\e
\007
\x7f
newline
return
tab
linefeed
backspace
tab verticale
bell
esc
un valore ascii ottale
un valore ascii hex
\cC
\\
\”
\l
\L
\u
\U
\E
un carattere di controllo (in questo caso control-C)
backslash
doppio accento
il prossimo carattere e’ minuscolo
tutte i prossimi caratteri sono minuscoli
il prox carattere e’ maiuscolo
tutti I prox caratteri sono maiuscoli
termina \L o \U
2
Operatori
 Operatori aritmetici : + - * / ** %
 NB:Calcoli internamente in virgola mobile
 Operatori logici di confronto :
 tra numeri
< <= > >= == !=
 tra stringhe
lt le gt ge eq ne
 NB : il confronto tra stringhe e’ diverso dal confronto tra numeri
 Operatori per stringhe :
 concatenazione : .
 ripetizione :
x
(es. “aaa”.”bbb” = aaabbb)
(es. ‘a’x3 = aaa)
 Conversione tra numeri e stringhe. Es. “F”.(“ 43” + 6) = “F49”
3
Variabili scalari
 Case sensitive
 Il valore di una variabile ‘nomevar’ e’ sempre identificato con $nomevar
 Operatori di assegnazione binaria : += *= .=
 Autoincremento, autodecremento:
++$a $a++
 Operatore chop(argomento) : elimina l’ultimo carattere dell’argomento. Ritorna il carattere eliminato
 Inserimento di variabili scalari in stringhe delimitate da “”
Es. $a=”bla bla $b bla bla” ;
 Se la variabile inserita viene seguita subito da testo, si puo’ usare il delimitatore {}
Es. $a=”blabla${b}bla” ; stesso risultato di $a=”blabla$b”.”bla” ;
 Lettura dalla tastiera : stringa <STDIN>
Es. $a=<STDIN> ; chop(a) ; oppure
chop($a=<STDIN>) ;
 Scrittura sullo standard output : print
Es. print(“blabla\n”) ;
oppure
print ”blabla\n” ;
4
Array in PERL
 Non ci sono limiti sul numero di elementi
 Variabili di tipo Array : individuate con il carattere @
Es. @a=(1,2,3) ;
@a=1 ;
# array di un solo elemento
@b=@a ;
@a=(“uno”, “due”, “tre”) ;
@b=(1,2,@a,3) ;
# @b contiene (1,2,”uno”,”due”,”tre”,3)
 Uso di variabili nell’array.
Es : ($a, $b, $c) = (1,2,3) ;
($a, $b) = ($b, $a) ;
($d, @z) = ($a, $b, $c) ;
($e, @z)=@z ;
#inizializza le variabili $a $b $c
#inverte
#risultato : $d=$a, @z=($b, $c)
#risultato : $e=$b, @z=($c)
 Se il numero di elementi non corrisponde : scarto elementi o undefined
 Assegnazione scalare=array : la var scalare contiene il numero di elementi
Es : @a=(1,2,3) ;
$b=@a ;
#risultato : la var b contiene 3
Ma : ($b) = @a ;
# la var b contiene il primo elemento di @a
5
Accesso agli elementi di un array
 Gli elementi di un array sono indiciati da 0
Es : @a=(1, 2, 3) ;
$b=$a[0] ;
#$b contiene 1
$a[0]=4 ;
#@a = (4,2,3)
$a[1]++;
$a[2] += 4;
 L’array puo’ essere riferito in parti con una notazione speciale:
Es :
@b=@a[0,1] ;
# equivale a @b=($a[0], $a[1]) ;
@a[0,1]=(x,y) ;
# come @a=(x,y)
@b=(1,2,3)[2,3];
# come @x=(1,2,3) @b=@x[2,3]
$x=0 ; $y=1 ;
@b=(1,2,3)[$x,$y] ;
@z=($x,$y) ;
@b=(1,2,3)[@z] ;
 Accedere ad un elemento non definito ritorna undef ; assegnare un elemento non definito estende l’array
 Massimo indice di un array :
$#a
6
Operatori per array
 push() e pop() :
aggiungono e tolgono elementi dal lato destro dell’array.
Es
push(@a,$x) ;
# come @a = (@a, $x)
$old=pop(@a) ;
push(@a,$x,$y,$z) ;
 shift() e unshift() : tolgono e aggiungono elementi dal lato sinistro dell’array
Es. unshift(@a, $x) ;
#come @a=($x,@a)
$x=shift(@a) ;
#come ($x,@a)=@a
 reverse() :
inverte l’ordine degli elemeti di un array
 sort() :
Es : @a=sort(@a) ;
ordina un array in senso ascendente.
 chop() :
se applicato ad un array, elimina l’ultimo elemento.
 Lettura da tastiera con <STDIN>
Es. : @a=<STDIN> ; #legge dallo standard input ogni riga in un elemento dell’array. Termina all’EOF (ctrl-D)
 Inserimento di elementi di array in variabili:
Es. @a=(1,2,3) ;
$b=”bla bla $a[1] bla” ;
$b=”bla bla @a bla” ;
$b=”blabla @a[1,2] bla” ;
7
Strutture di controllo in PERL
 Test:
if(espressione){
istruzioni ;
}else {
istruzioni ;
}
if(espressione) {
istruzioni ;
} elsif (espressione) {
istruzioni ;
} elsif(espressione) {
...
}
NB : se l’espressione e’ una stringa di singoli caratteri, l’espressione e’ valutata come segue :
se “0” => falso . Se non “0” => vero.
Es .
0
“0”
falso
“0”
falso
1-1
0
“0”
falso
“00”
vero
“”
falso
 unless : realizza la parte else dell’if :
unless(espressione){
istruzioni ;
}
8
Strutture di controllo in PERL
 while/until
while(espression){
istruzioni ;
}
until(espressione){
istruzioni ;
}
 for
for(iniziale ; test ; incremento)
istruzioni;
 foreach $varloop: la variabile di loop e’ un riferimento ad ogni elemento dell’array. L’array puo’ essere modificato. Se
non indico la variabile => variabile implicita $_
Es.
foreach $i (@array) {
istruzioni ;
}
9
Array associativi
 Collezione di dati scalari, individuati dal valore delle chiavi. Indicati con %nome
Es: %a=(“a”, dato_a, “b”, dato_b, “c”, dato_c);
 Accesso agli elementi di %a:
Es. print $a{“a”};
print $a{“b”};
$b=$a{$chiave};
 Inizializzazione elemento per elemento:
$a{“a”} = “dato_a”;
$a{“b”} = “dato_b”;
 Operatori per gli array associativi
 keys(): ritorna la lista di tutte le chiavi
Es: @lista = keys(%a);
# ritorna (“a”, “b”, “c”);
foreach $key (keys(%a)){ print “alla chiave $key corrisponde $a{$key}” }
# stampa la coppia chiave/valore
 each()
ritorna la coppia (chiave, dato)
Es. while( ($x,$y) = each(%a)) {
Print “$x $y”;
}
 delete
cancella un elemento dell’array associativo tramite la chiave
Es. delete $a(“a”);
10
Input/Output
 Lettura da <STDIN>
Es. $a = <STDIN> #legge una linea
@a = <STDIN> #legge tutte le linee fino a ^d
while(<STDIN>){
#legge in $_
chop;
#agisce su $_
# … elabora $_
}
 Operatore diamante < > : come STDIN ma legge una riga alla volta dai file forniti come argomenti dello script. NB: i
nomi vengono prelevati dall’array @ARGV
Es.: script ‘prova’
#!/usr/local/bin/perl
while(<>) {
print $_
}
prova file1 file2 …
 Uscita su STDOUT con print.
Es. $a = print(“blabla \n ») ;
#ritorna vero o falso
Print(“%s %d %f\n”, $a, $b, $c);
11
Espressioni regolari in PERL
 Racchiuse tra / /
Es.
funzione grep
#!/usr/local/bin/perl
while(<>){
if(/er/){
Print”$_”;
}
}
 Operatore di match =~ Applica una espressione regolare ad una variabile che non sia $_
Es.
$a=”blablabla”;
if($a =~ /^b/){
print $a
#stampa $a se la stringa inizia con b
}
print “continuare? (S/s o N/n)”
if(<STDIN> =~ /^[Ss]( {
print “hai risposto si!”
}
 Caratteri maiuscoli o minuscoli (ignora il case) con l’opzione i:
/er/i
12
 Inserimento di variabili:
Una ER puo’ contenere variabili. Le variabili vengono espanse prima di considerare eventuali caratteri speciali.
Es.
$a=”abc def ghi”;
print “scrivi una parola di 3 caratteri”;
$b=<STDIN>;
chop($b);
if($a =~ /$b/){
print “trovato $b in $a\n”;
} else {
print “non trovato\n”;
}
 Sostituzione in PERL:
s/old-ER/new-ER/
Es.
$_=”abc def ghi”;
s/abc/xyz/g;
#tutte le stringhe /abc/ vengono sostituite
$a=”abc def ghi”;
$a =~ s/abc/xyz/g;
 Operatore split(espressione regolare , stringa) : ritorna un vettore formato dalle parti della stringa che NON corrispondono
alla ER
Es.
$a=”a:b:c:d”;
@b=split(/:/, $a);
# @b contiene (a, b, c ,d)
@b=split(/er/);
# in questo caso la stringa e’ $_
 Operatore join($glue, @lista): riunisce gli elementi della lista attraverso $glue in una stringa
Es. $a = join(“:”, @b);
#ricostruisce la stringa precedente
13
Funzioni in PERL
 Il programmatore puo’ definire delle subroutine nella forma
sub nome{
Istruzioni;
}
 Le subroutine sono SOLO globali
 Chiamata di subroutine:
&nome
 La subroutine ritorna l’ultimo valore calcolato
Es.
sub somma{
$a+$b;
}
$a=2; $b=3;
$c=&somma;
Valori ritornati da un array:
sub lista{
($a, $b);
}
$a=2; $b=3;
@c=lista;
14
 Gli argomenti di una subroutine sono disponibili all’interno della subroutine come array locale alla subroutine chiamato
@_
Es.
sub somma{ $_[0] + $_[1]; }
print &somma(2, 3);
 Gli argomenti passati possono essere illimitati.
Es. somma di elementi
sub somma{
$x=0;
foreach $i (@_){
$x += $i;
}
$x;
# ultima espressione calcolata
}
$a = &somma(1,2,3,….,n);
 Definizione di variabili locali: operatore local()
Es.
sub somma{
local($a); local($i);
#oppure local($a,$b);
$a=0;
foreach $i (@_) {
$a += $i;
}
$a;
}
15
Es. Lista di tutti gli elementi maggiori di A:
sub somma{
local($n,@a);
($n,@a) = @_;
local(@b);
for($i=1;$i<$n; $i++){
if($a[$i]> A)
push(@b, $a[$i]);
}
@b;
}
@a=&somma(100,@lista);
oppure
sub somma{
local($n,@a);
($n,@a) = @_;
local(@b);
foreach $_ (@a){
if($_ > A)
push(@b, $_);
}
@b;
}
@a=&somma(100,@lista);
 Inizializzazione delle variabili locali:
local($n, @a) = @_;
oppure
local($n) = 0;
16
Gestione dei file in PERL
 Gestione dei file attraverso i file handle
 Apertura di un file handle: open(nome file handle, “nome file”);
o open ritorna vero o falso
o per aprire in scrittura:
open(OUT, “>nome file”);
o aggiungere al file:
open(OUT,”>>nome file”);
o apertura in lettura:
open(IN,”nome file”);
 Operatore die(“…”): scrive il messaggio e poi esce dal processo
Es. unless(open(OUT,”>file”)){
print(“errore\n”);
} else{
print(“ok\n”);
#resto del programma;
}
diventa:
unless(open(OUT,”>file”)){
die(“errore\n”);
} else{
print(“ok\n”);
#resto del programma;
}
oppure:
open(OUT,”>file”) || die(“errore\n”);
17
 Lettura file:
open(IN, “file”);
while(<IN>){
chop;
print “linea letta= $_ \n”:
}
close(IN);
 Copia file:
open(IN, “file_in”);
open(OUT, “>file_out”);
while(<IN>){
chop;
print(OUT, $_);
}
close(IN); close(OUT);
 Test sui file:
-r
-w
-x
-o
-R
-W
-X
-O
-e
file leggibile
file eseguibile
file o directory eseguibile
appartiene all’utente
leggibile dall’utente reale, non effettivo
scrivibile dall’utente reale
eseguibile dall’utente reale
appartiene all’utente reale
il file esiste
18
-z
-s
-f
-d
-l
-s
-p
-b
-c
-u
-g
-k
-t
-T
-B
-M
-A
-C
il file esiste ma ha dimensione nulla
esiste ed ha dimensione non nulla
file regolare
direttorio
link simbolico
socket
pipe con nome (fifo)
file speciale a blocchi
file speciale a caratteri
il file o directory ha il bit setuid settato
bit setgid settato
sticky bit settato
file testo
file binario
tempo dall’ultima modifica in giorni
tempo dall’ultimo accesso in giorni
tempo dall’ultima modifica dell’inode in giorni
 Operatore stat(file handle) :
ritorna informazioni dettagliate sui file.
Es: ($dev, $ino, $mode, $nlink, $UID, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat(handle);
 Per selezionare le informazioni:
 Operatore lstat(handle):
($uid, $gid) = (stat(“handle”))[4,5];
ritorna informazioni dettagliate su un link simbolico
19
Gestione delle directories
 Operatore chdir:
chdir(“directory”) || die
 Espansione degli argomenti (globbing): lista dei file corrispondenti alla espansione di *:
@a = <*>;
@a = <path*>;
Es.
while($b = <*>) {
print “$b”;
}
 Operatori opendir/closedir: gestione delle directory handle:
opendir(ETC,”/etc”) || die(“errore\n”);
 Operatore readdir(handle) : ritorna un nome file ($a=readdir) o tutti i nomi file (@a=readdir) contenuti nella directory
Es. nomi in ordine alfabetico.
opendir(ETC,”/etc”) || die;
foreach $a (sort readdir(ETC)){
print “$a\n”;
}
closedir(ETC);
20
Gestione file in PERL
 Cancellazione: unlink(nome). Ritorna il nr di file cancellati
Es. unlink(“nomefile”);
unlink(“file1”, “file2”, “file3”);
unlink(<*.txt>);
foreach $a (<*.txt>) {
unlink($a) || die;
}
foreach (<*.txt>){
unlink || die(“errore $_ \n”);
}
 Operatore rename($old, $new);
 Operatore link, symlink:
rinomina file.
introduce un link ad un file
Es.
Link(“old”,”new”)||die; #hard link
Symlink(“old”, “new”) || die; #link simbolico
 Operatore mkdir():
crea subdirectories
Es. Mkdir(“nomedir”, 0777);
 Operatore rmdir:
Es. Rmdir(“nomedir”);
cancella subdirectories
21
 Operatore chmod()
modifica i permessi del file; ritorna il nr di file modificati con successo
Es. $a=chmod(0666,”nomefile”);
Foreach $file (“nome1”, “nome2”){
Unless (chmod(0666, $file)) {
Print “errore nella modifica dei permessi!!\n”
}
}
 Operatore chown: modifica proprietario/gruppo
Es. chown(UID, GID, “file”);
:
# se 3290 = Pinco e 15006 = calcolat, la stessa operazione di chown Pinco nome1 nome2 e chrpp calcolat nome1 nome2
Chown(3290, 15006, “nome1”, “nome2”);
 Operatore utime(ultimo accesso, ultima modifica, files):
modifica I tempi
Tempi associati ad un file: data ultimo accesso, data ultima modifica, data ultima modifica dell’inode
Usando l’operatore time (ritorna il tempo corrente):
$a=time - 20*60;
utime($a, $a, “nome_file1”, “nome_file2”, …);
# 20 minuti da ora
# i file indicati sono aggiornati a 20 minuti fa
22
Gestione processi in PERL
 Creazione processi con la istruzione system; ritorna 0 se l’operazione ha avuto successo, altrimenti 1:
 system(“comando di shell”) && die;
 system(“comando1; comando2 > filek&”) && die;
 system(“comando > file”) && die;
 Creazione processi tramite gli accenti singoli ` `. NB: lo standard input/output del comando ` ` sono ereditati da PERL
Es.
$a = “data attuale = “ . `date`;
@a = `who`;
 Creazione processi tramite file handle:
Es.
Open(HANDLE, “who|”);
@a = <HANDLE>;
close(HANDLE);
#lettura
open(HANDLE, “|cat”);
#scrittura
print(HANDLE,”stringa da stampare con cat”);
close(HANDLE);
23
 Creazione processi con istruzioni fork/exec/wait: crea un clone del processo corrente. Fork ritorna 0 al figlio !0 al
padre
Es.
If(fork){
Print “sono il padre”;
}
else{
print “sono il figlio”;
exec(“date”);
}
unless (fork) {
exec(“date”);
}
wait;
# sono qui perche’ fork ritorna 0
 Uscita da un processo con exit;
 Variabile d’ambiente: l’ambiente viene messo nell’array associativo %ENV
Es.
for $a (sort keys %ENV){
# elenca le variabili d’ambiente
Print “$a = $ENV{$a}\n”;
}
$oldpath=$ENV(“PATH”);
# modifica le variabili d’ambiente
$ENV(“PATH”) = “ bla nuovo PATH bla”;
…
$ENV(“PATH”) = $oldpath;
24
Sommario delle operazioni sui processi:
system()
``
STDIN ereditato
“
STDOUT ereditato
STDOUT catturato
come stringa
STDERR ereditato
“
Atteso!
Atteso!
Open()
come output
Connesso al file
handle
STDOUT ereditato
STDERR ereditato
Atteso all’istante di close
Open() come
input
STDIN ereditato
STDOUT connesso
STDERR ereditato
Atteso all’istante di close
Fork, exec,
Wait
STDIN selezionato
dall’utente
STDOUT selezionato
dall’utente
STDERR selezionato
dall’utente
Selezionato dall’utente
25
Gestione Segnali in PERL
 Generazione di segnali:
kill (segnale, PIDs);
segnale numero o mnemonico.
Posso inviare segnali a piu’ PID – separati da virgola
 Cattura di segnali:
array associativo %SIG:
Es.
$SIG{‘INT} = ‘subroutine_name’;
$SIG{‘INT’} = ‘DEFAULT’;
sub subroutine_name{
istruzioni;
…
}
26
Conversione di altri linguaggi in PERL
 Semanticamente. PERL e’ un sovrainsieme di awk, ma non e’ sintatticamente compatibile con awk  a2p per la
conversione meccanica
 Similmente, semanticamente. PERL e’ un sovrainsieme di sed, ma non e’ sintatticamente compatibile con sed  s2p per
la conversione meccanica
 Esistono convertitori automatici per shell script? NO: la maggior parte delle cose non sono realizzate dallo script:
programmi esterni, confronto con numeri o stringhe etc. => non si guadagna niente!
27