通常、子プロセスは悪夢だと思います。次の場合:
#!/usr/bin/env bash
( proc_one ) &
( proc_two ) &
wait
このスクリプトを Ctrl-C キーを押してもバックグラウンドで実行され続け、端末に入力した内容はすべて中断されます。結局ターミナルを閉じました。
端末を介してサブプロセスを簡単に終了できるモードはありますか?
答え1
この問題を解決するためのいくつかのオプションがあります。
まず、端末に送信される出力を無視できます。ただし、これが邪魔にならない場合は、次のように端末に受け入れを停止するように指示できます。stty tostop
第二に、これらの仕事を殺すことができます。コマンドを使用して検索ps t
し、pidで終了します。
ウィンドウに出力が多すぎる場合は、別のウィンドウを開いてそこから終了できます。 (ただし、これはps t
通常では機能しません。tオプションに別のウィンドウのtty名を指定する必要があります。)またはtostopを使用して出力を停止してから終了します。
別の方法は、この問題を解決するためにスクリプトを変更することです。スクリプトが各プロセスを開始すると、各プロセスIDを記録して$!
変数に保存できます。その後、スクリプトはctrl-cをキャッチし、そのような場合はctrl-cを実行して終了する前に両方の操作自体を終了できます。
答え2
zzOneです。
#! /bin/bash
Killer () {
printf 1>&2 '\n.. Killing %s' "${Pids[@]}"
kill -SIGKILL "${Pids[@]}"
}
trap 'Killer' SIGINT
./zzTwo 5 4 & Pids+=( "${!}" )
./zzTwo 3 7 & Pids+=( "${!}" )
wait
printf 1>&2 '\n.. %s exits\n' "${$}"
以下はzzTwoです(異なる間隔でproc_xxxをエミュレートします)。
#! /bin/bash
for (( j = 0; j < "${1}"; j++ )); do
printf 1>&2 'Pid %d at %(%T)T\n' "${$}" -1
sleep "${2}"
done
printf 1>&2 'Pid %d exits at %(%T)T\n' "${$}" -1
そしてテストしてください:
$ ./zzOne
Pid 10951 at 22:35:28
Pid 10952 at 22:35:28
Pid 10951 at 22:35:32
Pid 10952 at 22:35:35
Pid 10951 at 22:35:36
^C
.. Killing 10951
.. Killing 10952
.. 10950 exits
$
少し冗長ですが、source
Killer機能を使用すると、複数のスクリプトに閉じ込められます。