J'ai un script qui tente d'établir une connexion à la base de données à l'aide d'un autre programme et dont le délai d'attente (2,5 min) est trop long. Je veux ajouter cette fonctionnalité au script.
Si la connexion prend plus de 5 secondes, arrêtez le processus
Sinon tuer le processus sommeil/tuer.
Le problème que je rencontre est la façon dont bash rend compte de la suppression d’un processus, c’est parce que les processus se trouvent dans le même shell, en arrière-plan. Existe-t-il un meilleur moyen de le faire ou comment puis-je faire taire le shell pour les commandes kill?
DB_CONNECTION_PROGRAM > $CONNECTFILE &
pid=$!
(sleep 5; kill $pid) &
sleep_pid=$!
wait $pid
# If the DB failed to connect after 5 seconds and was killed
status=$? #Kill returns 128+n (fatal error)
if [ $status -gt 128 ]; then
no_connection="ERROR: Timeout while trying to connect to $dbserver"
else # If it connected kill the sleep and any errors collect
kill $sleep_pid
no_connection=`sed -n '/^ERROR:/,$p' $CONNECTFILE`
fi
Je ne sais pas si c'est identique mais j'ai résolu un problème similaire il y a quelques années. Cependant, je suis un programmeur, pas un administrateur système de type Unix, donc prenez ce qui suit avec un grain de sel, car mon Bash-fu n'est peut-être pas aussi puissant ...
Fondamentalement, j'ai fait fourche, fourche et fourchette:)
Out of memory Après avoir retrouvé mon ancien code (que j’utilise étonnamment tous les jours) parce que ma mémoire n’était pas suffisante, dans Bash cela fonctionnait un peu comme ceci:
commandThatMayHang.sh 2 > /dev/null 2>&1 & (notice that last '&', we're forking)
MAYBE_HUNG_PID=$!
sleepAndMaybeKill.sh $MAYBE_HUNG_PID 2 > /dev/null 2>&1 & (we're forking again)
SLEEP_AND_MAYBE_KILL_PID=$!
wait $MAYBE_HUNG_PID > /dev/null 2>&1
if [ $? -eq 0 ]
# commandThatMayHand.sh did not hang, fine, no need to monitor it anymore
kill -9 $SLEEP_AND_MAYBE_KILL 2> /dev/null 2>&1
fi
où sleepAndMaybeKill.sh dort la durée souhaitée puis tue commandThatMayHand.sh .
Donc, fondamentalement, les deux scénarios sont les suivants:
votre commande se termine bien (avant votre délai de 5 secondes ou autre) et ainsi le attendez arrête dès que votre commande se termine bien (et tue le "tueur" car il n'est plus nécessaire
la commande se verrouille, le tueur finit par tuer la commande
Dans tous les cas, vous êtes assuré de réussir dès que la commande est terminée ou d’échouer après le délai.
Il existe un utilitaire GNU coreutils appelé timeout: http://www.gnu.org/s/coreutils/manual/html_node/timeout-invocation.html
Si vous l'avez sur votre plate-forme, vous pouvez faire:
timeout 5 CONNECT_TO_DB
if [ $? -eq 124 ]; then
# Timeout occurred
else
# No hang
fi
J'ai trouvé ce script bash timeout.sh D'Anthony Thyssen ( his web ). Cela semble bon.
Voulez-vous dire que vous ne voulez pas que le message d'erreur soit imprimé si le processus n'est pas encore en cours d'exécution? Ensuite, vous pouvez simplement rediriger stderr
: kill $pid 2>/dev/null
.
Vous pouvez également vérifier si le processus est toujours en cours d'exécution:
if ps -p $pid >/dev/null; then kill $pid; fi