Trappole: rendi i tuoi script bash più robusti

Navigando nella rete nazionale mi sono imbattuto in un file articolo interessante (che porto qui testualmente perché è magistralmente spiegato) dove il suo autore ci mostra come rendere i nostri script bash più robusti usando Trappole.

Rendi i tuoi script bash più robusti con le trappole

Immagina di avere uno script bash che viene eseguito ogni giorno ogni sei ore e che a un certo punto fallisce o che lo stesso script viene eseguito due volte contemporaneamente. Queste due situazioni sono abbastanza scomode poiché richiedono l'intervento umano per essere corrette o in determinati momenti non possono essere affrontate, lasciando il sistema in uno stato incoerente. La soluzione a questo, tra l'altro, è usare le trappole.

Traps è un modo semplice ed efficace per controllare l'output degli script bash. Torniamo alla stessa situazione iniziale, se lo script viene fermato manualmente, ad esempio con ctrl-c, viene interrotto restituendo il segnale in uscita

INT

e se finisce con

kill

allora l'output sarebbe

TERM.

Tutti i possibili codici di uscita possono essere visualizzati con

kill -l

tuttavia le più utilizzate sono appunto

INT, TERMINE, USCITA

Se lo script consiste, ad esempio, nella sincronizzazione dei file con

rsync

la cosa più sensata è fare affidamento su un file di blocco che non consente l'esecuzione simultanea dello script:

LOCK = "/ var / run / rsync.lock" se [! -e $ LOCK]; quindi tocca $ LOCK rsync -avz foo bar rm $ LOCK altrimenti echo "rsync è già in esecuzione" fi

In semplice spagnolo, lo script precedente controlla se il file di blocco esiste e se non esiste, lo crea e successivamente esegue il comando corrispondente, eliminando infine il file di blocco. Se il file esiste, lo script invia semplicemente un messaggio all'utente indicando che il comando è già in esecuzione.

Tuttavia, quando si verifica una situazione problematica può accadere che il file di blocco non venga eliminato, rovinando gli effetti indesiderati. La soluzione è molto semplice:

LOCK = "/ var / run / rsync.lock" se [! -e $ LOCK]; quindi trap "rm -f $ LOCK; exit" INT TERM EXIT tocca $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT else echo "rsync è già in esecuzione" fi

La particolarità di questa soluzione è che il comando è racchiuso in una trappola, in modo che quando si riceve un segnale

INT, TERMINE, USCITA

lo script si ferma e cancella il file di blocco.

Vale la pena dire che potrebbe esserci una situazione di concorrenza nello script sopra tra il momento in cui il file di blocco viene verificato e il momento in cui viene creato. Una possibile soluzione sarebbe quella di utilizzare un reindirizzamento e la modalità noclobber di bash che non reindirizza a un file esistente:

LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; quindi trap 'rm -f "$ LOCK"; exit $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync è già in esecuzione: $ (cat $ LCK)" fi

La particolarità di quest'ultima è che viene utilizzata, come avevo già detto, la modalità noclobber e che il file di lock contiene il PID del processo che si sta eseguendo.

Vale anche la pena ricordare che esistono altre soluzioni come

flock

o

solo

tuttavia in questo post ho voluto condividere le soluzioni con le risorse proprie di bash. Puoi imparare un po 'di più sulle trappole con questo ottima guida.


Lascia un tuo commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati con *

*

*

  1. Responsabile dei dati: Miguel Ángel Gatón
  2. Scopo dei dati: controllo SPAM, gestione commenti.
  3. Legittimazione: il tuo consenso
  4. Comunicazione dei dati: I dati non saranno oggetto di comunicazione a terzi se non per obbligo di legge.
  5. Archiviazione dati: database ospitato da Occentus Networks (UE)
  6. Diritti: in qualsiasi momento puoi limitare, recuperare ed eliminare le tue informazioni.

  1.   Raffaele Castro suddetto

    Grande! Grazie per la condivisione.

  2.   nx suddetto

    Bell'articolo, cambia solo 'echo "rsync è già in esecuzione: $ (cat $ LCK)"' in 'echo "rsync è già in esecuzione: $ (cat $ LOCK)"'

    saluti

  3.   dglangos suddetto

    Un articolo molto interessante, sissignore! Questo lo tengo.

  4.   Joaquin suddetto

    È un comando molto utile da tenere a mente. L'ho usato in uno script che ho pubblicato in un post, per eliminare alcuni file che lo script ha creato quando è stato interrotto.

  5.   DaniFP suddetto

    Molto interessante, sissignore.