スクリプトを実行するとします
$ Nohup ./myscript </dev/null >/dev/null 2>&1 &
そしてそれを殺します
$ pkill myscript
SIGKILL
信号を受信したときに別のコマンドが実行されるように、スクリプトをどのように設計できますか?
SIGKILL
(およびSIGSTOP
)をキャッチできないため、SIGKILL
のカスタムハンドラーを有効にすると意味がありません。
他のすべての信号をキャッチできるので、おそらくそれらを中心に設計してみてください。
また、実行中:
pkill myscript
デフォルトのpkill
は、SIGTERM
ではなく、SIGKILL
を送信します。これは明らかにキャッチできます。
たとえば、スクリプト内の上部に次を追加します。
trap 'echo foobar' TERM
trap
Shellビルトインは、シグナルをトラップし、カスタムハンドラーをディスパッチするか、シグナルを完全に無視するために使用されます。
ここでは、シェルがTERM
を受信すると、コマンドecho foobar
が実行されます。
他の信号にも同じことができ、必要に応じてコマンドを変更することもできます。たとえば、echo foobar
とカスタムハンドラスクリプトの両方の実行:
trap 'echo foobar; /my/custom/handler.sh' TERM
その後exit
を計画している場合:
trap 'echo foobar; /my/custom/handler.sh; exit' TERM
SIGKILLをキャッチできないという回答を受け入れました。ところで、スクリプトのPIDを監視して、スクリプトがまだ実行中かどうかを確認できます。これは、現在のスクリプトのサブプロセスでこのウォッチャーを起動することでも実行できます。
#!/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"
https://stackoverflow.com/a/39128574/1324228からのオリジナルトラップスクリプト