以非交互方式终止shell函数

时间:2013-04-03 18:05:13

标签: shell zsh

有没有办法在不杀死正在运行它的shell的情况下以非交互方式终止shell函数

我知道可以告诉shell如何响应信号(例如USR1),但我无法弄清楚信号处理程序如何终止该函数。

如果有必要,您可以假设要终止的功能是以“可终止的”方式写入的。 (即通过宣布一些合适的选择)。

(我立即感兴趣的是如何为zsh执行此操作,但我也有兴趣知道如何为bash/bin/sh执行此操作。)< / p>

编辑:回应Rob Watt的建议:

% donothing () { echo $$; sleep 1000000 }
% donothing
47139

如果此时我在运行shell的同一终端点击Ctrl-C,那么函数donothing确实终止了,我得到命令提示符。但如果相反,从不同的shell会话中,我运行

% kill -s INT 47139

... donothing函数终止。

1 个答案:

答案 0 :(得分:1)

也许我不完全明白你想要什么,但也许是这样的?

trap "stopme=1" 2

function longcycle() {
    last=$1
    for i in 1 2 3 4 5 
    do
        [ ! -z "$stopme" ] && return
        echo $i
        sleep 1
    done
}

stopme=""
echo "Start 1st cycle"
longcycle
echo "1st cycle end"

echo "2nd cycle"
stopme=""
longcycle
echo "2nd cycle end"

以上是针对bash的。运行它,然后尝试按CTRL-C。

或者对于not interactively,请保存以上内容,例如my_command,然后尝试:

$ ./my_command &  #into background
$ kill -2 $! #send CTRL-C to the bg process

编辑:

bash中sleep示例的解决方案:

$ donothing() { trap '[[ $mypid ]] && trap - 2 && kill $mypid' 0 2; sleep 1000000 & mypid=$!;wait; }
$ donothing

当您从另一个终端发送信号时将终止它。记住,发出'0'je'正常结束的过程“的信号。语义名称:0 = EXIT,2 = INT ......等。

并且还记得,信号是将发送到进程而不是函数。在你的例子中,进程是当前的(交互式shell),所以必须使用等待技巧来获得一些可中断的东西...不是一个很好的解决方案 - 但是当想要中断在交互式shell中运行的东西的唯一方法(不是来自另一个终端的分叉的......