您可以在使用 () 创建的子 shell 中指定一个单独的陷阱吗?

您可以在使用 () 创建的子 shell 中指定一个单独的陷阱吗?

我正在编写一个脚本来启动一个子 shell 来执行一些工作。在特殊情况下,脚本需要告诉子 shell 彻底停止正在执行的操作并提前退出。但是,我下面的伪代码似乎不起作用。我正在尝试不可能的事情吗?是否可以在子 shell 中为信号定义单独的陷阱?

#!/bin/bash

function myExitFunction { ... }
trap myExitFunction SIGTERM

while [ 1 ] ; do
    waitForSpecialCondition

    kill -0 $SUBSHELL_PID   # check if subshell is running
    if [ $? -eq 0 ] ; then  # and kill it if it is
        kill $SUBSHELL_PID
    fi

    (
    someProcess
    MYOWNCHILD=$!           # save someProcess's pid to kill later if I need to
    trap "kill $MYOWNCHILD" SIGTERM
    ... # do stuff
    ) &
    SUBSHELL_PID=$!

done

答案1

事实证明我的问题并不是我真正想的那样。下面是一个行为类似于上面的伪代码的脚本。它的功能完全符合我的预期(尽管为了简单而做了一些设计),并且是为父 shell 进程和子 shell 进程设置单独的信号陷阱的一个很好的例子。

只需运行脚本并按 ctrl-c 退出即可演示此陷阱功能。

#!/bin/bash

function endEarly {
echo "Terminating early"
if [ ! -z $SUBSHELL_PID ] ; then
    echo "Killing subshell with pid $SUBSHELL_PID"
    kill $SUBSHELL_PID
fi
exit
}

trap endEarly SIGTERM SIGINT

echo "Give me some input"
while [ 1 ] ; do
    read INPUT

    # kill the subshell if it exists and is running
    if [ ! -z $SUBSHELL_PID ] ; then
        kill -0 $SUBSHELL_PID
        if [ $? -eq 0 ] ; then
            kill $SUBSHELL_PID
        fi
    fi

    echo "Now I'll repeat your input.  Feel free to change it"
    echo "at any time by typing it again and hitting <Enter>"
    {
        (
            while [ 1 ] ; do
                echo "$INPUT"
                sleep 5
            done
        ) &
        CHILD_PID=$!
        trap "kill $CHILD_PID;" SIGTERM SIGINT
        wait $CHILD_PID
    } &
    SUBSHELL_PID=$!
done

相关内容