グループでバックグラウンドプロセスを開始し、すべて終了します。

グループでバックグラウンドプロセスを開始し、すべて終了します。

ある日、私は誰かを殺すために台本を書こうとしました。PIDすべてのサブプロセスがありますが、時間が経つと信頼できないと思います。なぜなら、いくつかのサブプロセスは次のような結果をもたらします。PPID~の1

今私が探しているのは、バックグラウンドで次の関数を実行し、この関数とcurlすべての関数を同じままにする方法です。グループそして、中断したら、そのスクリプトを終了し、バックグラウンドに残っているすべての添字を終了します。

download(){
    until curl -s -S -L -A Mozilla/5.0 -m 300 "$@"; do
        echo Retrying in 5 seconds... >&2
        sleep 5
    done
}

for url in foo.com bar.com baz.com; do
    download $url >$url &
done
wait

これは必要ありませんが、downloadこのスクリプトで何度も使用する関数なので、ここに含めました。そして私が決めた最大時間制限は300ただし、curl一部のネットワークエラーによって中断されることがあります。

ベストアンサー1

job通常、インタラクティブシェルからスクリプトを呼び出すと新しいプロセスグループ(別名)に配置されるため、そのスクリプトをCtrl-C使用すると、そのスクリプトによって開始されたすべてのプロセスがSIGINTを受け取ります。

バックグラウンドで(まだインタラクティブシェルで)起動すると、それは独自のプロセスグループでも起動されます。

次の方法でプロセスグループについて学ぶことができます。

ps -j

(シェルを管理できるように、プロセスグループでコマンドラインを実行する動作をj示しますjob control(フォアグラウンド/バックグラウンド/キル/一時停止/再開)。

あなたはについて学ぶことができます働くjobsコマンドを使用して対話型シェルを開きます(すべてのプロセスを含むわけではありません)。jobs -pプロセスグループIDが表示されます。

-xxプロセスグループIDがどこにあるかを通知して、プロセスグループのメンバーを終了できます。PGID)またはで作業仕様を使用してください%job-number。例:

$ sleep 30 | sleep 40 &
[1] 6950 6951
$ ps -j
  PID  PGID   SID TTY          TIME CMD
 6031  6031  6031 pts/3    00:00:00 zsh
 6950  6950  6031 pts/3    00:00:00 sleep
 6951  6950  6031 pts/3    00:00:00 sleep
 6952  6952  6031 pts/3    00:00:00 ps
$ kill -- -6950
[1]  + terminated  sleep 30 | sleep 40
$ sleep 30 | sleep 40 &
[1] 6955 6957
$ jobs
[1]  + running    sleep 30 | sleep 40
$ kill %1
[1]  + terminated  sleep 30 | sleep 40

対話型シェルで実行しないと、スクリプトは親プロセスと同じプロセスグループになります。したがって、そのプロセスグループを終了すると、終了したくない他のプロセスが終了する可能性があります。

スクリプトで実行できることは、プロセスグループを直接起動することです。

以下を追加するのと同じです。

[ "$(ps -o pgid= -p "$$")" -eq "$$" ] ||
  exec perl -e 'setpgrp or die "setpgrp; $!"; exec @ARGV' -- "$0" "$@"

(私たちがプロセスグループリーダーではないことが確認された場合は、スクリプトの先頭perlでstart new process groupを呼び出してスクリプトを再実行してください。)

これにより、スクリプトが独自のプロセスグループで実行されることを保証できます。

しかし、これは次のことを意味します。

something | myscript | something

対話型シェルでは、myscriptおそらくプロセスグループリーダーではありません。上記の操作を実行すると、setpgrpスクリプトは端末のフォアグラウンドプロセスグループになくなったためCtrl-C終了しません。

おすすめ記事