web-dev-qa-db-ja.com

()で作成したサブシェルに別のトラップを指定できますか?

サブシェルを開始して作業を開始するスクリプトを作成しています。特別な場合、スクリプトはサブシェルに、実行中の処理を完全に停止して早期に終了するように指示する必要があります。ただし、以下の私の擬似コードは機能していないようです。私は不可能を試みていますか?サブシェル内の信号に個別のトラップを定義することは可能ですか?

#!/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
Cory Klein

私の問題は、私が実際に思っていたものではなかったことがわかりました。以下は、上記の擬似コードのように動作するスクリプトです。これは、私が期待したとおりに機能し(単純にするために少し工夫されていますが)、親シェルプロセスと子シェルプロセスに別々のシグナルトラップがある良い例です。

このトラップ機能は、スクリプトを実行し、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
2
Cory Klein