如何正确sigint从另一个bash脚本运行的bash脚本?

时间:2014-08-27 15:47:48

标签: linux bash shell kill

我有两个脚本,其中一个调用另一个脚本,需要在一段时间后将其删除。下面给出了一个非常基本的工作实例。

main_script.sh:

#!/bin/bash
cd "${0%/*}" #make current working directory the folder of this script
./record.sh &
PID=$!
# perform some other commands
sleep 5
kill -s SIGINT $PID
#wait $PID
echo "Finished"

record.sh:

#!/bin/bash
cd "${0%/*}" #make current working directory the folder of this script
RECORD_PIDS=1
printf "WallTimeStart: %f\n\n" $(date +%s.%N) >> test.txt
top -b -p $RECORD_PIDS -d 1.00 >> test.txt
printf "WallTimeEnd: %f\n\n" $(date +%s.%N) >> test.txt

现在,如果我运行main_script.sh,它将不能很好地关闭record.sh on the finish:top命令将继续在后台运行(test.txt将增长,直到你手动终止顶级进程),即使main_script完成,使用SIGINT终止记录脚本。

如果我按住c / c main_script.sh,一切都会正常关闭。如果我自己运行record.sh并按ctrl + c它,一切都会正常关闭。

如果我取消注释等待,脚本将挂起,我将需要ctrl + z它。

我已经尝试了各种各样的事情,包括在接收SIGINT,EXIT和/或SIGTERM时使用'trap'来启动一些清理脚本,但没有任何效果。我也尝试使用fg将record.sh带回前台,但这也没有帮助。我已经找了将近一天了,不幸的是现在运气好了。我做了一个丑陋的解决方法,使用pidof找到顶级进程并手动终止它(从main_script.sh),然后我必须手动编写“WallTimeEnd”语句到main_script.sh。对我来说不是很满意......

期待任何提示!

干杯, 柯恩

1 个答案:

答案 0 :(得分:3)

您的问题是SIGINT已发送至bash而不是top。一种选择是使用新会话并将信号发送到进程组,例如:

#!/bin/bash
cd "${0%/*}" #make current working directory the folder of this script
setsid ./record.sh &
PID=$!
# perform some other commands
sleep 5
kill -s SIGINT -$PID
wait $PID
echo "Finished"

这会启动新流程组中的子脚本,-pid会告诉kill发出该群组中每个流程的信号,其中包含top