1

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

我知道可以告诉 shell 如何响应信号(例如USR1),但我不知道信号处理程序将如何终止函数。

如有必要,您可以假设要终止的函数已经以“可终止”的方式编写(即通过声明一些合适的选项)。

(我的直接兴趣是如何为 执行此操作zsh,但我也有兴趣知道如何为bash和执行此操作/bin/sh。)

编辑:响应 Rob Watt 的建议:

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

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

% kill -s INT 47139

...donothing函数不会终止

4

1 回答 1

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

编辑:

sleep您在 bash 中的示例的解决方案:

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

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

也请记住,信号发送到进程而不是函数。在您的示例中,该进程是当前(交互式外壳),因此必须使用等待技巧来获得可中断的东西......不是一个好的解决方案 - 但是当想要中断交互式外壳中正在运行的东西时的唯一方法(不是一个分叉的)来自另一个终端......

于 2013-04-03T19:58:20.233 回答