如何正确sigint从另一个bash脚本运行的bash脚本?
问题描述:
我有两个脚本,其中一个正在调用另一个脚本,并且需要在一段时间后终止它。下面给出一个非常基本的工作示例。如何正确sigint从另一个bash脚本运行的bash脚本?
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:top命令会继续在后台运行(test.txt会增长,直到您手动终止顶层进程),即使main_script完成并且使用SIGINT来终止记录脚本。
如果我ctrl + c的main_script.sh,一切都正常关闭。如果我自己运行record.sh,并按ctrl + c,那么所有东西都会正常关闭。
如果我取消注释等待,脚本将挂起,我将需要ctrl + z它。
我已经尝试了各种各样的东西,包括使用“陷阱”在接收到SIGINT,EXIT和/或SIGTERM时启动一些清理脚本,但没有任何工作。我也尝试使用fg将record.sh带回到前台,但那也没有帮助。我一直在寻找近一天,现在很幸运。我制作了一个丑陋的解决方法,它使用pidof来查找顶层进程并手动(从main_script.sh中)杀死它,然后我必须从main_script.sh手动编写“WallTimeEnd”语句。对我来说不是很满意...
期待任何提示!
干杯, 公园
答
你的问题是,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
。
完美!最后作品! – koenlek 2014-08-27 16:23:58
这在没有“setid”命令的Mac上不起作用。 – 2017-08-22 00:36:49