我有两个脚本,其中一个调用另一个脚本,需要在一段时间后将其删除。下面给出了一个非常基本的工作实例。
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。对我来说不是很满意......
期待任何提示!
干杯, 柯恩
答案 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
。