bash:退出脚本循环
问题描述:
我正在使用zgrep - 在压缩文件上运行grep的bash脚本包装器。bash:退出脚本循环
问题是,控制 - c不会停止脚本。 我想是因为循环遍历文件,产生子shell,所以终止信号转到正在运行的grep进程,而不是父脚本。所以即使陷入父母脚本也不行。
来说明:
trap break SIGPIPE SIGTERM SIGQUIT SIGSTOP
for i
gzip -cdfq "$i" | grep $pattern
done
我也试过"/bin/kill -- -$$"
代替break
,具有相同的结果。我猜这个脚本没有得到中断。
任何想法如何解决这个问题?
答
我很惊讶你的C-c不工作(你可能想看看stty
)。不过,你的脚本有几个问题。
-
trap
命令也应停止在SIGINT
。 - 陷阱中的
break
不会让你走出循环。你会需要这样的东西:
DONE= trap 'DONE=1' SIGINT for i in "[email protected]"; do [[ -n $DONE ]] && break ∶
答
每bash
信息文档:
如果bash等待命令完成并接收信号 为其陷阱已定,直到 命令完成后,陷阱才会被执行。
如果你想改变它的话,你需要编写一个封装器来让你更好地控制信号。
答
我得到类似的陷阱行为(没有得到执行)。我的环境是HP Unix
上的ksh88
。我的陷阱是赶上INT KILL
和QUIT
。我在shell函数中调用gzip
。如果我删除gzip
陷阱处理程序得到执行时,我发送中断信号,但不是当我有gzip
。
关于你的问题:Cntrl-C
不会阻止你的循环的原因是因为你正在捕捉你的陷阱。而你的陷阱处理程序是不正确的命令来停止你的循环。你的父母脚本不会停止,因为它看不到任何信号,再次因为'陷阱'你说你想处理它而不是壳。如果你只想退出循环,那么把你的循环放在一个单独的函数中,并在该函数中设置陷阱。只给你一个想法,这里是a.ksh
:
function f1
{
trap return INT QUIT KILL
i=0
while [[ $i -lt 100 ]]
do
$((i=$i+1))
sleep 2
echo $i
done
}
echo BEFORE calling f1
f1
echo AFTER calling f1
测试。KSH:
$ a.ksh
BEFORE calling f1
1
2
3
以后打电话F1
我第三次迭代后击中Contrl-C
。正如你看到我得到AFTER calling f1
消息,这意味着contrl-C
只是停止了功能不是整个过程(a.ksh
)。希望有所帮助。
是的,但是信号也会传递给程序,因此(通常)会尽早终止信号,然后陷阱会发出聪明的声音。 – bobbogo 2011-03-14 18:43:21