シェルフォークが元のものより長く生き残るのを防ぎますか?

シェルフォークが元のものより長く生き残るのを防ぎますか?

次のようなBashスクリプトがある場合:

function repeat {
    while :; do
        echo repeating; sleep 1
    done
}
repeat &
echo running once

running once一度印刷されますが、repeatフォークは永遠に存在し、無限に印刷されます。

repeatこれを生成したスクリプトが終了した後も引き続き実行されないようにするにはどうすればよいですか?

bash -c新しいインタプリタを明示的にインスタンス化すると、親プロセスが消えたため強制的に終了すると思われましたが、孤児プロセスはinitPID 1によって採用されているようです。

別のファイルでこれをテストしてください。

# repeat.bash
while :; do echo repeating; sleep 1; done

# fork.bash
bash -c "./repeat.bash & echo an exiting command"

実行すると、バックグラウンドで実行され./fork.bash続けます。repeat.bash

簡単で怠惰な解決策は、次の行を追加することですfork.bash

pkill repeat.bash

ただし、他の重要なプロセスではこの名前を使用しないことをお勧めします。それ以外の場合は名前も消去されます。

  1. バックグラウンドジョブを生成したスクリプト(またはプロセス)が終了したときに終了する必要がある分岐シェルで、バックグラウンドジョブを処理するためのより優れた許容可能な方法があるかどうか疑問に思います。

  2. すべてのプロセスで同じ名前を盲目的に使用するよりも良い方法がない場合は、pkillingネットワークサーバーと同じように実行されている冗長タスクを処理して終了する必要がありますか?cronスクリプトがgitリポジトリにあり、コードを変更せずに自分で含める必要があるため、作業を避けたいと思います/etc/

ベストアンサー1

スクリプトが終了する前にバックグラウンドプロセスが終了します。

trap '[ "$pid" ] && kill "$pid"' EXIT

function repeat {
    while :; do
        echo repeating; sleep 1
    done
}
repeat &
pid=$!
echo running once

どのように動作しますか?

  • trap '[ "$pid" ] && kill "$pid"' EXIT

    これは。スクリプトが終了しようとするたびに、単一引用符で囲まれたコマンドが実行されます。このコマンドは、シェル変数にNULL以外のpid値が指定されていることを確認します。存在する場合、そのプロセスに関連するプロセスはpid終了します。

  • pid=$!

    これにより、前のバックグラウンドcommand()のプロセスIDがrepeat &シェル変数に保存されますpid

改善する

〜のようにパトリックコメントで指摘したように、スクリプトが終了する可能性があります。後ろにバックグラウンドプロセスが開始されますが、今後変数がpid設定されました。次のコードを使用してこの状況を処理できます。

my_exit() {
    [ "$racing" ] && pid=$!
    [ "$pid" ] && kill "$pid"
}
trap my_exit EXIT

function repeat {
    while :; do
        echo repeating; sleep 1
    done
}

racing=Y
repeat &
pid=$!
racing=

echo running once

おすすめ記事