Pour les scripts shell, j'ai tendance à utiliser l'option mkdir
sur flock
car cela rend les serrures plus portables.
De toute façon, en utilisant set -e
n'est pas suffisant. Cela ne quitte le script que si une commande échoue. Vos verrous seront toujours laissés derrière.
Pour un nettoyage correct des verrous, vous devriez vraiment configurer vos pièges comme ce psuedo code (repris, simplifié et non testé mais provenant de scripts utilisés activement) :
#=======================================================================
# Predefined Global Variables
#=======================================================================
TMPDIR=/tmp/myapp
[[ ! -d $TMP_DIR ]] \
&& mkdir -p $TMP_DIR \
&& chmod 700 $TMPDIR
LOCK_DIR=$TMP_DIR/lock
#=======================================================================
# Functions
#=======================================================================
function mklock {
__lockdir="$LOCK_DIR/$(date +%s.%N).$$" # Private Global. Use Epoch.Nano.PID
# If it can create $LOCK_DIR then no other instance is running
if $(mkdir $LOCK_DIR)
then
mkdir $__lockdir # create this instance's specific lock in queue
LOCK_EXISTS=true # Global
else
echo "FATAL: Lock already exists. Another copy is running or manually lock clean up required."
exit 1001 # Or work out some sleep_while_execution_lock elsewhere
fi
}
function rmlock {
[[ ! -d $__lockdir ]] \
&& echo "WARNING: Lock is missing. $__lockdir does not exist" \
|| rmdir $__lockdir
}
#-----------------------------------------------------------------------
# Private Signal Traps Functions {{{2
#
# DANGER: SIGKILL cannot be trapped. So, try not to `kill -9 PID` or
# there will be *NO CLEAN UP*. You'll have to manually remove
# any locks in place.
#-----------------------------------------------------------------------
function __sig_exit {
# Place your clean up logic here
# Remove the LOCK
[[ -n $LOCK_EXISTS ]] && rmlock
}
function __sig_int {
echo "WARNING: SIGINT caught"
exit 1002
}
function __sig_quit {
echo "SIGQUIT caught"
exit 1003
}
function __sig_term {
echo "WARNING: SIGTERM caught"
exit 1015
}
#=======================================================================
# Main
#=======================================================================
# Set TRAPs
trap __sig_exit EXIT # SIGEXIT
trap __sig_int INT # SIGINT
trap __sig_quit QUIT # SIGQUIT
trap __sig_term TERM # SIGTERM
mklock
# CODE
exit # No need for cleanup code here being in the __sig_exit trap function
Voici ce qui va se passer. Tous les pièges produiront une sortie, donc la fonction __sig_exit
se produira toujours (sauf en cas de SIGKILL), ce qui nettoie vos serrures.
Remarque : mes valeurs de sortie ne sont pas des valeurs basses. Pourquoi ? Divers systèmes de traitement par lots font ou font attendre les chiffres de 0 à 31. En les réglant sur autre chose, je peux faire en sorte que mes scripts et mes flux de lots réagissent en conséquence au travail de lot ou script précédent.