Bashによって開始された子プロセスを簡単に終了することはできません。

Bashによって開始された子プロセスを簡単に終了することはできません。

通常、子プロセスは悪夢だと思います。次の場合:

#!/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
$ 

少し冗長ですが、sourceKiller機能を使用すると、複数のスクリプトに閉じ込められます。

関連情報