web-dev-qa-db-fra.com

Exécuter une autre commande lorsque mon script reçoit le signal SIGKILL

Supposons que je lance un script

$ Nohup ./myscript </dev/null >/dev/null 2>&1 & 

puis tuez-le

$ pkill myscript

Comment mon script peut-il être conçu de manière à exécuter une autre commande lorsqu'il reçoit le signal SIGKILL?

1
user123456

Vous ne pouvez pas attraper SIGKILL (et SIGSTOP), l'activation de votre gestionnaire personnalisé pour SIGKILL est donc sans objet.

Vous pouvez capter tous les autres signaux, alors essayez peut-être de créer un motif autour de ceux-ci.

Aussi en faisant:

pkill myscript

être par défaut pkill enverra SIGTERM, pas SIGKILL, qui peut évidemment être attrapé.

Par exemple, dans votre script, en haut, ajoutez:

trap 'echo foobar' TERM

Le shell intégré trap sert à intercepter un signal et à envoyer tout gestionnaire personnalisé, ou à ignorer complètement le signal.

Ici, la commande echo foobar sera exécutée lorsque le shell recevra TERM.

Vous pouvez également faire de même pour d’autres signaux et modifier la commande en fonction de vos besoins. Par exemple, en exécutant echo foobar et en exécutant un script de gestionnaire personnalisé:

trap 'echo foobar; /my/custom/handler.sh' TERM

Si vous avez l'intention de exit après cela:

trap 'echo foobar; /my/custom/handler.sh; exit' TERM
3
heemayl

A accepté la réponse dit, vous ne pouvez pas attraper SIGKILL. En passant, vous pouvez toujours rechercher le PID de votre script pour voir s'il est toujours en cours d'exécution. Cela peut même être fait en lançant cet observateur dans un sous-processus de votre script actuel:

#!/bin/bash

# Launch a sleeping child process that will be "waited" next
sleep infinity & PID=$!

# Trap "graceful" kills and use them to kill the sleeping child
trap "kill $PID" TERM

# Launch a subprocess not attached to this script that will trigger
# commands after its end
( sh -c "
    # Watch main script PID. Sleep duration can be ajusted 
    # depending on reaction speed you want
    while [ -e /proc/$$ ]; do sleep 3; done

    # Kill the infinite sleep if it's still running
    [ -e /proc/$PID ] && kill $PID

    # Commands to launch after any stop
    echo "Terminating"

" & )    

# Commands to launch before waiting
echo "Starting"

# Waiting for infinite sleep to end...
wait

# Commands to launch after graceful stop
echo "Graceful ending"

Script d'interruption d'origine provenant de https://stackoverflow.com/a/39128574/1324228

1
JBreton