Con il Perl esistono vari modi per integrare tra loro più programmi esterni,
richiamandoli in modo opportuno da uno script in modo che cooperino per la
soluzione del problema posto. Brian W. Kernighan [7] nella prefazione di
un suo famoso volume, nel sostenere che UNIX è un sistema operativo assai
potente ed efficace, asserisce che il punto centrale è costituito dal concetto
che la forza di un sistema nasce più dall'interazione tra i programmi che non
dai programmi veri e propri. Se presi isolatamente -sostiene Kernighan- molti
programmi UNIX compiono dei lavori banali, ma combinati con altri, diventano
strumenti utilissimi e generalizzati. Il Perl consente di realizzare questa
integrazione in modo assai versatile ed efficiente.
I modi usati più comunemente per interagire con programmi esterni attraverso
uno script in Perl sono sostanzialmente tre:
- mediante gli apici inversi;
- mediante la funzione system o la funzione exec;
- mediante l'apertura di un canale di pipe.
Vediamo in estrema sintesi queste tre tecniche.
Chiamata mediante apici inversi
È il modo più semplice e diretto di richiamare un programma esterno.
Sostanzialmente in questo modo si lancia un processo figlio che esegue il suo
compito e restituisce l'output come valore di ritorno, senza visualizzare nulla
sullo STDOUT.
Ad esempio per inserire la data corrente nella variabile $data si
può utilizzare la seguente chiamata:
$data= `date +%d/%m/%y`;
Chiaramente si possono eseguire operazioni anche molto più complesse di
questa, magari concatenando in un pipe più chimate. Ad esempio per
leggere un file di input ($file) ordinandone le righe e selezionando
solo quelle che contengono la stringa $s si può usare la seguente
espressione:
@linee = `cat $file | grep $s | sort`
Le funzioni system ed exec
Queste due funzioni aprono un processo figlio e lo eseguono interamente
(senza intercettarne l'output come per l'esecuzione di programmi mediante gli
apici inversi).
Se l'esecuzione di un programma esterno viene effettuata mediante la funzione
system, allora lo script aspetterà che il programma esterno sia
completamente terminato prima di riprendere l'esecuzione dall'istruzione
successiva alla system.
Con la chiamata exec invece lo script termina l'esecuzione e passa
definitivamente il controllo al programma esterno richiamato.
Esecuzione mediante il canale di pipe
Aprendo un programma esterno come se fosse un file in modalità di
``piping'', se ne possono sfruttare le funzionalità da uno script in
Perl.
Ad esempio, supponiamo di voler visualizzare il contenuto di un array,
impaginando l'output mediante il comando UNIX more. Il seguente
frammento di script fornisce una possibile implementazione:
open (OUT, "| more") || die "Errore\n\n";
foreach $riga (@array) {
print OUT $riga;
}
close(OUT);
Un esempio un po' più sofisticato è il seguente. Supponiamo di voler inviare
per posta elettronica ad un certo indirizzo l'output del nostro script; il
seguente frammento di codice suggerisce una possibile implementazione (in questo
caso sfrutteremo il comando mail disponibile su numerosi sistemi UNIX):
$indirizzo = 'liverani@mat.uniroma1.it';
open (MAIL, "| /bin/mail $indirizzo") || die "Impossibile inviare
il messaggio all'indirizzo $indirizzo.\n\n";
print MAIL <<"END";
Subject: Risultato dello script
Lo script ha prodotto il seguente risultato...
END
close(MAIL);