2014-08-27 152 views
0

我有两个脚本,其中一个正在调用另一个脚本,并且需要在一段时间后终止它。下面给出一个非常基本的工作示例。如何正确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”语句。对我来说不是很满意...

期待任何提示!

干杯, 公园

回答

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

+0

完美!最后作品! – koenlek 2014-08-27 16:23:58

+0

这在没有“setid”命令的Mac上不起作用。 – 2017-08-22 00:36:49