いくつかのタスクを実行するためにサブシェルを起動するスクリプトを作成しています。特別な場合、スクリプトはサブシェルに実行中の操作を完全に停止し、早く終了するように指示する必要があります。しかし、以下の擬似コードは機能しないようです。私は不可能な仕事を試みているか。サブシェルの信号に対して別々のトラップを定義できますか?
#!/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
知っていると、私の問題は私が思ったのとは違っていました。以下は、上記の擬似コードと同様に動作するスクリプトです。これは私が期待したように正確に動作し(単純化のためにもう少し設計されていますが)、親シェルプロセスとサブシェルプロセスに別々の信号トラップを設定する良い例です。
単にスクリプトを実行して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