同一bash进程中有多个陷阱

时间:2018-12-20 00:59:44

标签: bash shell signals

我想在.bashrc中加入几个功能。 这些功能可能会执行很长时间,因此我希望能够使用CTRL+C杀死它们,并在发生这种情况时打印一些信息。我可以通过捕获CTRL+C来捕获SIGINT,但是我不确定为同一脚本(.bashrc)中的不同函数设置不同陷阱处理程序的正确方法是什么。

我想出了这个似乎可行的解决方案:

function foo()
{
    trap 'echo "foo() stopped"' SIGINT
    while true; do
        sleep 1
        echo "foo() working..."
    done
}

function bar()
{
    trap 'echo "bar() stopped"' SIGINT
    while true; do
        sleep 1
        echo "bar() working..."
    done
}

示例输出:

$ foo
foo() working...
foo() working...
^Cfoo() stopped

$ bar
bar() working...
bar() working...
^Cbar() stopped

现在,我的问题是:

  1. 我是否正确理解我每次在函数中执行trap ...时都会为整个bash会话(进程)重置信号处理程序吗?还是每次都创建一个新的处理程序?
  2. 这通常是一个好的解决方案,还是有更好的解决方案?

1 个答案:

答案 0 :(得分:3)

是的,陷阱正在全局重置事物。函数结束时将其重置为其原始值可能会很好。像这样:

foo() {
        old=$(trap -p SIGINT)
        trap 'echo "foo() stopped"' SIGINT
        ...
        eval set -- "$old"
        trap "$3" SIGINT
}

OTOH,将功能作为子外壳运行可能会更健壮,这将只为该子外壳设置陷阱。这样做就像在函数定义中使用()一样简单:

foo()
(
    trap 'echo "foo() stopped"' SIGINT
    while true; do
        sleep 1
        echo "foo() working..."
    done
)