以下是一个示例脚本simple.sh
,它启动后台进程,向其发送信号,并验证信号是否已被处理:
#!/bin/bash
function on_signal() {
echo "1 caught $1, exiting!"
exit 0
}
function my_sleep {
trap "on_signal $1" $1
echo "1 mypid=$$"
echo "1 mybashpid=$BASHPID"
echo "1 start sleep"
for i in {1..10};
do
echo "1 sleeping $i"
sleep 1
done
echo "1 failed"
exit 1
}
signal=SIGINT
if [[ ! -z $1 ]]; then
signal=$1
fi
my_sleep $signal &
sleeppid=$!
echo ">>> sleeppid=$sleeppid"
sleep 1 # to give script time to run trap
echo ">>> sending $signal"
kill -$signal $sleeppid
for i in 0.25 0.5 1 2; do
echo ">>> trying $i"
if kill -0 $sleeppid 2> /dev/null; then
echo ">>> still running..."
sleep $i
else
echo ">> success"
exit 0
fi
done
echo "Failure"
exit 1
现在,当我运行./simple.sh
时,它运行正常。当我在后台运行它./simple.sh &
时,它也可以正常工作。但是,当我添加一个在后台运行w1.sh
的包装器simple.sh
时,它会突然停止工作:
#!/bin/bash
./simple1.sh $1 &
现在./w1.sh
会产生Failure
。为什么呢?
我已经阅读了https://www.cons.org/cracauer/sigint.html,它提供了非常丰富的信息,但我仍然无法理解子进程本身的行为方式会有所不同,具体取决于调用它的上下文。
注意:我知道一个“解决方法”让它按照我想要的方式运行(w1.sh
应该在子shell中调用(./simple.sh $1) &
),但我想了解那里发生了什么,以及解决方法的工作原理。
谢谢!