Ciao a tutti, mi è stato chiesto in ufficio di realizzare uno script particolare. Siccome vengono prodotti file di ingenti dimensioni si è pensato ad un sistema in grado di comprimere tali file .Nel realizzare questo programma ho cercato di fare una cosa il più generica possibile per poterla utilizzare anche in altri ambienti. Lo script riconosce i file in base all'estensione e viene configurato per lavorare in una certa directory indipendentemente dalla directory dalla quale viene lanciato. Di seguito le specifiche:

  1. Un file per archivio
  2. l'archivio deve rimanere nella stessa cartella nella quale si trova il file
  3. Verifica dell'archivio per sapere se tutto è andato a buon fine
  4. Cancellazione del file originale in caso affermativo.

Tutto lo script si configura mediante le variabili d'ambiente all'inizio dello stesso. Le estensioni vanno inserite separate da uno spazio e non devono includere punti nè altri caratteri speciali perchè vengono utilizzate in mezzo a delle espressioni regolari. Per la compressione viene usato il comando 7z che ci viene fornito dal pacchetto p7zip-full.
 

#!/bin/bash
#Script config variables
extensions="cad bak"
directory="./"
errorLog="compattaCad.log"
#1 Fastest 3 Fast 5 Normal 7 Maximum 9 Ultra
export compressionLevel=5

#DO NOT EDIT AFTER THIS LINE
#Returns the tail of extensions
function ctail {
  shift
  echo $*
}

function chead {
  echo $1
}

#Parameters: file to compress
function makeArchive {
  echo "compressing $1.7z"
  7z a -mx=$compressionLevel $1.7z $1 >/dev/null
  if [ $? -ne 0 ]; then
    date >> $errorLog
    echo "Error compressing $(pwd)/$1" >> $errorLog
    echo "Error compressing $(pwd)/$1"
    exit 1
  fi
  echo "checking $1.7z"
  7z t $1.7z >/dev/null
  if [ $? -ne 0 ]; then
    date >> $errorLog
    echo "Error checking $(pwd)/$1" >> $errorLog
    echo "Error checking $(pwd)/$1"
    exit 1
  fi
  rm $1
}

#main
#Part which finds files to compress
command="find $directory -regex .*\.$(chead $extensions)$"
for i in $(ctail $extensions)
do
  command="$command\|.*\.$i$"
done
export -f makeArchive
$command -execdir bash -c "makeArchive '{}'" \;

if [ $? -eq 0 ]; then
  echo good
else
  echo Error!
fi
exit 0

Le prime funzioni servono a prelevare la testa e la coda della lista di estensioni. Questo serve perchè la prima estensione ha una sequenza di caratteri speciali diversa dalle successive. Il ciclo for successivo aggiunge poi le altre n-1 estensioni alla stringa dell'espressione condizionale. I caratteri speciali tipo '.', '/' e l'ultimo '$' vengono utilizzati nelle espressioni condizionali, che sono delle stringhe che si utilizzano principalmente per cercare dei pattern in altre stringhe, in questo caso rilevare tutti e soli i file le quali estensioni corrispondono a quelle cercate. Dopo il ciclo for viene esportata la funzione makeArchive che verrà utilizzata per comprimere i file. Se una compressione non va a buon fine, viene registrato su un file di log la data ed il file che ha generato l'errore. Ovviamente il file non verrà cancellato. La linea successiva lancia find, un programma utile per trovare file, che lancerà a sua volta tante volte makeArchive quanti sono i file trovati. Tale funzione si occuperà anche di cancellare i file se la compressione è avvenuta con successo. Finite le compressioni viene rilevato il valore di ritorno di find (0 se ogni archivio è stato compattato con successo, 1 se almeno un archivio ha avuto dei problemi) per stampare un messaggio di errore.
Spero che questo script possa essere utile a qualcuno e se avete idee per delle possibili modifiche l'area dei commenti è a vostra disposizione.