按Ctrl-C停止bash脚本,但不要停止脚本调用的PHP脚本

我需要每隔几分钟运行几个脚本。 这个逻辑是用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 ,当它正在hibernate的时候,它会杀死bash脚本,但是不会杀死被调用的php脚本。 我知道有一个不同的进程运行它。

那么,有没有办法杀死bash脚本和每个“孩子”? 还是应该用另一种方法来运行这些脚本?

从这个答案: bash – 如何杀死shell的所有subprocess? – 堆栈溢出 。

如果你只关心杀死直接的孩子,你应该能够做到

 pkill -P $$ 

-P

 -P, --parent ppid,... Only match processes whose parent process ID is listed. 

$$表示当前进程的PID。

如果你需要杀死subprocess和可能启动的任何进程(孙辈等),那么你应该能够使用与该问题不同的函数:

 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 } 

你可以更新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 }