2011-03-09 155 views
1

我正在使用zgrep - 在压缩文件上运行grep的bash脚本包装器。bash:退出脚本循环

问题是,控制 - c不会停止脚本。 我想是因为循环遍历文件,产生子shell,所以终止信号转到正在运行的grep进程,而不是父脚本。所以即使陷入父母脚本也不行。

来说明:

trap break SIGPIPE SIGTERM SIGQUIT SIGSTOP 
for i 
    gzip -cdfq "$i" | grep $pattern 
done 

我也试过"/bin/kill -- -$$"代替break,具有相同的结果。我猜这个脚本没有得到中断。

任何想法如何解决这个问题?

回答

0

我很惊讶你的C-c不工作(你可能想看看stty)。不过,你的脚本有几个问题。

  1. trap命令也应停止在SIGINT
  2. 陷阱中的break不会让你走出循环。你会需要这样的东西:
 
DONE= 
trap 'DONE=1' SIGINT 
for i in "[email protected]"; do 
    [[ -n $DONE ]] && break 
    ∶ 
0

bash信息文档:

如果bash等待命令完成并接收信号 为其陷阱已定,直到 命令完成后,陷阱才会被执行。

如果你想改变它的话,你需要编写一个封装器来让你更好地控制信号。

+0

是的,但是信号也会传递给程序,因此(通常)会尽早终止信号,然后陷阱会发出聪明的声音。 – bobbogo 2011-03-14 18:43:21

0

我得到类似的陷阱行为(没有得到执行)。我的环境是HP Unix上的ksh88。我的陷阱是赶上INT KILLQUIT。我在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)。希望有所帮助。