数分ごとにいくつかのスクリプトを実行する必要があります。ロジックは PHP で作成されており、問題なく動作しています。まとめるために、以下の bash スクリプトを作成しましたが、これも問題なく動作します。
#!/bin/bash
calculaDiff() {
DIFF=0
while [ "$DIFF" -eq "0" ]; do
DIFF=`php calculaDiff.php`
done;
}
# need to calculate pending diffs
calculaDiff
# main loop
while true; do
CAPTURA=`php capturaRelatorio.php`
if [ "$CAPTURA" -eq "0" ]; then
calculaDiff
fi
VERIFICA=`php verificaLimites.php`
done
スクリプトcapturaRelatorio.php
にはスリープが含まれています。これは、N 分ごとにしか処理できないためです。監視できるように、S 秒間スリープしていることを示すメッセージが出力されます。
このとき、 bash スクリプトを呼び出してCtrl+を押すとC、スリープ中に bash スクリプトは強制終了されますが、呼び出された php スクリプトは強制終了されません。別のプロセスが実行されていることは理解しています。
では、bash スクリプトとすべての「子」を強制終了する方法はありますか? それとも、これらのスクリプトを実行するために別の方法を採用する必要がありますか?
答え1
この回答から:bash - シェルのすべてのサブプロセスを強制終了するにはどうすればいいですか? - Stack Overflow。
直系の子供を殺すことだけを気にするなら、
pkill -P $$
-P
言う
-P, --parent ppid,...
Only match processes whose parent process ID is listed.
そして、$$
現在のプロセスの PID を意味します。
子プロセスと、それによって開始される可能性のあるプロセス (孫など) を終了する必要がある場合は、その質問に対する別の回答にある関数を使用できるはずです。
kill_descendant_processes() {
local pid="$1"
local and_self="${2:-false}"
if children="$(pgrep -P "$pid")"; then
for child in $children; do
kill_descendant_processes "$child" true
done
fi
if [[ "$and_self" == true ]]; then
kill "$pid"
fi
}
このような
kill_descendant_processes $$ true
これにより、現在のプロセスとすべての子孫が強制終了されます。おそらく、これをトラップ ハンドラーから呼び出す必要があるでしょう。つまり、ctrl+ を押すとcスクリプトが送信されSIGINT
、そのシグナルをキャッチして処理できます。例:
trap cleanup INT
cleanup() {
kill_descendant_processes $$ true
}
答え2
bash スクリプトを更新して、ctrl+c をトラップできます。
trap control_c SIGINT
function control_c() {
echo "## Trapped CTRL-C"
ps -ef | grep php | grep -v grep | awk '{ print $2 }' > php.kill
for i in $(cat php.kill)
do
kill -9 $i > /dev/null
done
rm php.kill
}