Automatizzar e con Perl e Bash LinuxDay 2007 Torino Cascina Roccafranca Francesco Golia e Igor Pesando
Introduzion e Questo “seminario” vuole solamente dare un'idea di quello che si può fare con semplici scripit in perl e bash. NON richiede alcuna conoscenza a priori di perl e bash e per questo l'esempio sarà molto semplice. L'unico prerequisito è conoscere qualche comando di bash. In rete si trovano molti tutorial.
Assunzione: tutti files da ridurre sono in una stessa cartella “originali” Crea una catella "modificati" Per ogni file nella cartella “originali” fai la riduzione Sposta i files nella cartella "modificati" Pseudocodice per creare delle thumbnails
● Useremo il programma convert della suite ImageMagic ( ● Per convertire il file rose.jpg nel file th50_rose.png riscalato del 50% convert rose.jpg -resize 50% th50_rose.png ● Per convertire il file rose.jpg nel file th50px_rose.png di 50px di larghezza (mantendo il rapporto larghezza/altezza) convert rose.jpg -resize 50 th50px_rose.png Il commando per un singolo file
Il programma minimale perl Programma converti_v0.pl: #!/usr/bin/perl -w $src_dir=$ARGV[0]; $convert_prog='convert'; $new_size='50%'; qx{mkdir $src_dir/thumbnails}; foreach $file ( qx{ls $src_dir} ) { chomp $file; qx{$convert_prog $src_dir/$file -resize $new_size th_50_$file}; qx{mv th_50_$file $src_dir/thumbnails}; } Uso: perl converti_v0.pl nome_della_cartella_originali
Esempio di risultato Supponiamo che la cartella foto contenga i seguenti file P01.JPG P02.JPG P03.JPG P04.JPG Dando il comando perl converti_v0.pl /home/igor/foto si creerà una sottocartella in foto col nome thumbnails che conterrà i file th_50_P01.JPG th_50_P02.JPG th_50_P03.JPG th_50_P04.JPG ottenuti riducendo del 50% i file originali
Spiegazione (1) La linea $src_dir=$ARGV[0]; ci insegna diverse cose: tutti i comandi in perl terminano con ; (punto e virgola) tutte le variabili iniziano col $ (dollaro) ==> $src_dir il primo argomento passato al comando si chiama $ARGV[0] esempio per tutte le altre spiegazioni: perl convert_v0.pl foto $ARGV[0] foto Significato: uso una variabili il cui nome mi spiega il contenuto
Spiegazione (2) La linea $convert_prog='convert'; dice che la variable $convert_prog (comincia con $ !) contiene convert Notate gli apici che fanno da contenitore. Mutatis mutande con $new_size='50%';
Spiegazione (3) La linea qx{mkdir $src_dir/thumbnails}; esegue il comando (shell) mkdir foto/thumbnails e crea la sottocartella thumbnails della cartella foto (ricordate che stiamo vedendo che succede col comando perl convert_v0.pl foto per cui $src_dir foto )
Spiegazione (4) La linea foreach $file ( “lista di cose” ) {.... comandi.... } con “lista di cose” = qx{ls $src_dir} Ora “lista di cose” sarà qualcosa come P01.JPG P02.JPG P03.JPG P04.JPG Il comando fa assumere a $file il valore P01.JPG ed esegue tutti i comandi; poi $file vale P02.JPG e tutti i comandi vengono eseguiti; fino a quando $file vale P04.JPG
Spiegazione (5) Il comando all'interno del foreach qx{$convert_prog $src_dir/$file -resize $new_size th_50_$file}; esegue, quando $file vale P01.JPG, il comando convert foto/P01.JPG -resize 50% th_50_P01.JPG e similmente per tutti gli altri valori
Osservazion i ● Il programma precedente ha molti limiti ● la riduzione è fissa ● non controlla si sia veramente dato il nome della cartella ● non controlla che la sottocartella sia stata veramente creata ● non controlla che i file su cui si agisce con convert siano file grafici e non cartelle
Il programma non minimale (1) #!/usr/bin/perl -w $src_dir=$ARGV[0]; $new_size=$ARGV[1]; $convert_prog='convert'; #controlliamo di aver convert installato nel sistema if(not defined( qx {$convert_prog -version} ) ){ print STDERR "ERRORE: $convert_prog non e' installato\n"; exit 1; } $identify_prog='identify'; #controlliamo di aver identify installato nel sistema if( not defined( qx {$identify_prog -version} ) ){ print STDERR "PROBLEMA: $identify_prog non e' installato\n"; $use_identify=0; } else { $use_identify=1; } # controlliamo di avera dato abbastanza parametri if( $#ARGV < 1 ){ print STDERR "Uso:\n$0 cartella_foto rescaling\n"; exit 1; }
Il programma non minimale (2) # controlliamo che il primo parametro sia una cartella if( not (-d $src_dir) ){ print STDERR "ERRORE: $src_dir non e' una cartella!\n"; exit 1; } # controlliamo che il secondo parametro sia un rescaling # attenzione se passiamo una percentuale dobbiamo usare gli apici es. '15%' if ( $new_size !~ m/[0-9]+%?/ ){ print STDERR "ERRORE: $new_size non e' un rescaling valido!\n"; exit 1; } # ora trasformo per esempio 50%-> 50 e 30->30px in modo da poter usare la # variabile $ns nel nome delle thumbnail $ns=$new_size; if( $ns !~ s/%//){ $ns.= 'px';} # creiamo la sottocartella if ( system('mkdir', "$src_dir/thumbnails") ){ print STDERR "ERRORE: non ho potuto creare $src_dir/thumbnails!\n"; exit 1; }
Il programma non minimale (3) foreach $file (qx{ls $src_dir} ) { chomp $file; # controlla che $file sia veramente un file next if ( -d $file ); # controlla che $file sia un'immagine gestibile da convert next if ( $use_identify && system ($identify_prog,'-quiet',"$src_dir/$file") ); print "Sto convertendo $file\n"; qx{$convert_prog $src_dir/$file -resize $new_size th_${ns}_$file}; qx{mv th_${ns}_$file $src_dir/thumbnails}; }
BAS H ● The Bourne Again SHell ● Nei sistemi UNIX Like sono presenti diversi tipi di shell (es. sh,bash,csh,tcsh,ksh). ● BASH è una versione potenziata di SH, che ne mantiene la compatibiliità ed è la shell standard di un sistema GNU/Linux ● Scrivere uno script in bash significa quindi riunire in un file una sequenza di comandi che potreste scrivere direttamente sul terminale ● In genere però scriviamo sul terminale comandi molto semplici (cd, mkdir, ls etc...) rispetto alle possibilità che ci offre la shell. ● Dunque bash ci permette di sia creare uno script con i comandi di uso quotidiano sia di creare un programma più corposo con operatori, funzioni e controlli di flusso
BAS H Punto e virgola In molti linguaggi di programmazione le istruzioni terminano con il punto e virgola. In bash invece no, il punto e virgola serve per scrivere sulla stessa riga due comandi che devono essere eseguiti in sequenza. Variabili Le variabili in bash si definiscono così NOME=”valore” export NOME=”valore” e possono essere chiamate in modi diversi: $NOME ${NOME} comoda se var annegata in una stringa
BAS H Abbiamo visto come convertire le immagini con convert usando perl Vediamo come si può fare con BASH
BASH – Convertire le immagini (1) #!/bin/bash export SRC_DIR=$1 export NEW_SIZE=$2 export CONVERT_PROG=convert # prova a lanciare convert $CONVERT_PROG -version # se il codice restituito dall'ultima esecuzione è maggiore di 0 c'è stato qualche problema if [ $? -gt 0 ] ; then echo "ERRORE : convert (imagemagick) non è installato" 1>&2 exit 1 fi # controllo che ci siano almeno 2 parametri if [ $# -lt 2 ]; then echo "Uso:\n$0 cartella_foto rescaling\n" 1>&2 exit 1 fi # controllo che il primo parametro in input sia una cartella if [ ! -d $SRC_DIR ]; then echo "ERRORE: $SRC_DIR non e' una cartella!\n" 1>&2 exit 1 fi
BASH – Convertire le immagini (2) # crea la directory thumbnails sotto la directory dei sorgenti se non esiste già if [ ! -e $SRC_DIR/thumbnails ]; then mkdir $SRC_DIR/thumbnails fi # rimuovo il simbolo % per poter usare il parametro nel nome del file export NS=$(echo $2 | sed s/%//) export NS="${NS}px" # vado alla directory con gli originali cd $SRC_DIR for file in $(ls *jpg ) ; do echo "Converto il file $file in thumbnails/th_$NS_$file" $CONVERT_PROG $file -resize $NEW_SIZE thumbnails/th_${NS}_$file done
BASH – Creare una pagina html vedi i files