bash:退出脚本循环

时间:2011-03-09 08:25:01

标签: bash

我正在使用zgrep - 一个在压缩文件上运行grep的bash脚本包装器。

问题是 control - c 不会停止脚本。 我想原因是文件循环产生子shell,因此终止信号转到正在运行的grep进程,而不是父脚本。因此,即使父脚本中的陷阱也不起作用。

说明:

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

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

知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

我很惊讶你的C-c不起作用(你可能想看看stty)。然而,您的脚本存在一些问题。

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

答案 1 :(得分:0)

根据bash信息文档:

  

如果Bash正在等待命令完成并收到信号   已经设置了陷阱,陷阱将不会执行,直到   命令完成。

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

答案 2 :(得分:0)

我通过陷阱得到了类似的行为(没有被执行)。 ksh88上的我的环境为HP Unix。我的陷阱是抓住INT KILLQUIT。我在shell函数中调用gzip。如果我删除gzip,当我向其发送中断信号时,陷阱处理程序会被执行,但是当我有gzip时则不会执行。

关于你的问题:Cntrl-C不会停止你的循环的原因是你被陷阱捕获它。并且您的陷阱处理程序不是正确的命令来停止循环。你的父脚本也不会停止,因为它没有看到任何信号,再次因为'陷阱'你说要处理它而不是shell。如果你想退出循环,那么把你的循环放在一个单独的函数中,并在该函数中设置陷阱。只是为了给你一个想法,这里是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

测试a.ksh:

 $ a.ksh

BEFORE calling f1 

1

2

3

调用f1后


我在第三次迭代后点击Contrl-C。如您所见,我收到了AFTER calling f1消息,这意味着contrl-C刚刚停止了该功能而不是整个过程(a.ksh)。希望有所帮助。