背景
私は記事を読んだ郵便はがき信号処理に関して、SIGINT
対話型シェルと非インタラクティブシェルの両方で選択し、使用するコードで信号を正しく処理する方法はまだ理解されていません。
私のスクリプトの簡単な例を見て、特定の部分について質問します。
はい
どこでも入手して使用できる便利な機能を備えたスクリプトがあります。
/tmp/useful_functions.sh
#!/bin/bash
function example()
{
echo "Main script started"
# Make process run forever in the background.
( while sleep 1; do echo "Background script running"; done ) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
}
テスト1
使用しようはい別のスクリプト内で実行してください。
/tmp/test.sh
#!/bin/bash
source /tmp/useful_functions.sh
example
それでは、サブシェルが動作している間に実行して/tmp/test.sh
押してみましょう。 (サブシェル=)Control-C
$(sleep 10; echo "Subshell completed")
なぜなら。 。 。結果Test 1
/tmp/test.sh
、、、プロセスexample
が終了しました。 プロンプトが新しい入力を待っています。subshell
background
質問
SIGINT
プロセス間転送/処理/伝播の順序は何ですか?
(メンションはSIGINT
次のアドレスに送信する必要があります。すべての視聴者最も内側のプロセスは最初に処理する必要があります。 )- バックグラウンドプロセスが終了するのはなぜですか?
テスト2
使用しようはいインタラクティブBashで直接実行する:
...$ source /tmp/useful_functions.sh
...$ example
Control-C
サブシェルが機能したら、もう一度押します。
(サブシェル= $(sleep 10; echo "Subshell completed")
)
なぜなら。 。 。結果Test 2
example
プロセスはsubshell
終了しましたが、backgrounded
プロセスはアクティブのままです。プロセスの出力が印刷されても、
プロンプトはまだ新しい入力を待っています。backgrounded
質問
SIGINT
プロセス間転送/処理/伝播の順序は何ですか?- バックグラウンドプロセスが今終了しないのはなぜですか?
改善された例
動作を完全には理解していませんが、Test 1
この動作は私が期待する動作であり、インタラクティブなBashでこれを達成したいと思います。
バックグラウンドプロセスと既存のサブシェルを包む別のサブシェルを作成し、新しいプロセスが終了すると、バックグラウンドプロセスと既存のサブシェルも終了することを望むアイデアです。
/tmp/useful_functions.sh
#!/bin/bash
function example()
{
(
echo "Main script started"
# Make process run forever in the background.
( while sleep 1; do echo "Background script running"; done ) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
)
}
重複した結果Test 1
/tmp/test.sh
、example
およびプロセスがouter subshell
終了しました。プロンプトが新しい入力を待っています。inner subshell
background
質問
SIGINT
プロセス間転送/処理/伝播の順序は何ですか?- バックグラウンドプロセスが終了するのはなぜですか?
重複した結果Test 2
example
、、、プロセスouter subshell
が終了しました。 プロンプトが新しい入力を待っています。inner subshell
background
質問
SIGINT
プロセス間転送/処理/伝播の順序は何ですか?- バックグラウンドプロセスが終了するのはなぜですか?
質問
SIGINT
この時点で、私は実際にバックグラウンドプロセスの後にクリーンアップを行う必要があることと、それを処理するどこかにキャプチャする必要があることに気づきました。
解決策
私はBashで一般的に処理と伝播がどのように行われているのか分からないので、SIGINT
知識に基づいた推測を行い、効果があると思いましたが、わからない解決策を思い出しました。
#!/bin/bash
function example()
{
(
echo "Main script started"
# Make process run forever in the background.
(
trap "echo Cleanup; trap - SIGINT; kill -s SIGINT ${$}" SIGINT
while sleep 1; do echo "Background script running"; done
) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
)
}
質問
- 私のトラップは正しく処理/伝播されますか
SIGINT
? - これが
${$}
正しいプロセスですか?
(言及された投稿ではプロセスは自分で終了する必要があると言いますが、例では${$}
これを代わりに使用します${BASHPID}
。)