我有一个简单的脚本:
f=1 # initial value
loop(){
...
if [[ $f -eq 1 ]]
then
echo $msg1
f=2
(sleep $interval; loop) &
exit 1
elif [[ $f -eq 2 ]]
then
echo $msg2
f=1
(sleep $interval; loop) &
exit 2
fi
...
}
旨在保持这两个消息之间的循环。我这样做不是正常的while循环,因为我希望脚本在后台运行。因此,我期望在终端中发生的事情是:
gt@gt:~./timer.sh
<msg1>
gt@gt:~<me running some other commands>
<some output>
gt@gt:~<as soon as $interval time gets over>
<msg2>
gt@gt:~<fresh prompt>
如您所见,我希望msg2出现在显示正常回声输出的位置,然后紧接着它应该为命令输入留下新的提示。但是实际发生的是:
gt@gt:~./timer.sh
<msg1>
gt@gt:~<me running some other commands>
<some output>
gt@gt:~<msg2>
<same prompt is still waiting for input here>
如何解决这个问题?
您可以通过运行#!/bin/bash
并设置sleep=3
秒数来本地验证此问题。
让您的计时器脚本将SIGINT
信号发送到父进程($PPID
)。
#!/bin/bash
echo "Going to interrupt $PPID in 5 seconds"
sleep 5
echo "More output"
kill -SIGINT $PPID
sleep 5
当该脚本在后台(./script &
)中运行时,它应该发送输出,进入睡眠状态,然后发送更多输出,然后强制重新绘制提示。
该脚本将再次休眠,然后退出。
f=1 # initial value
loop(){
...
if [[ $f -eq 1 ]]
then
echo $msg1
kill -SIGINT $PPID
f=2
(sleep $interval; loop) &
exit 1
elif [[ $f -eq 2 ]]
then
echo $msg2
kill -SIGINT $PPID
f=1
(sleep $interval; loop) &
exit 2
fi
...
}
当您的shell进程被信号中断时,您将丢失待处理的输入行,但是在计时器脚本输出之后,将重新绘制命令提示符。
要在子脚本中重现此行为,请将父PID环境变量从调用者脚本传递到子脚本中。
main.sh
...
./timer.sh $PPID
...
#exits
timer.sh
...
# Save the parent pid argument
gp=$1
...
# Replace instances of $PPID with $gp in timer.sh
...
kill -SIGINT $gp
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句