[編集:これは、生成されたすべてのプロセスを終了する方法を尋ねる他の質問と似ています。答えはすべてpkillを使用しているようです。だから私の質問の中核はおそらく:スクリプトによって生成されたすべてのプロセスにCtrl-C / Zを伝播する方法はありますか? ]
coreutilsのコマンドを使用してSoXを呼び出す場合(議論rec
)timeout
ここ)、Bashスクリプトから呼び出されると、キーストロークでそれを終了する方法がないようです。
例:
timeout 10 rec test.wav
Ctrl... bashで+CまたはCtrl+を使用して終了できますが、Zスクリプト内で呼び出すときはそうではありません。
timeout 10 ping nowhere
Ctrl... bashで+CまたはCtrl+で終了することができますZ。 +はスクリプト内で実行されるときですCtrl。Z
プロセスIDを見つけて終了できますが、標準の割り込みキーを押すことができないのはなぜですか?私のスクリプトを設定する方法はありますか?
答え1
Ctrl+シグナルキーがCフォアグラウンドのすべてのプロセスにシグナルを送信するのを待ちます。プロセスグループ。
通常、プロセスグループはパイプです。たとえば、head <somefile | sort
実行中のプロセスhead
と実行中のプロセスはsort
シェルと同じプロセスグループにあるため、両方がシグナルを受け取ります。somecommand &
バックグラウンドでジョブを実行している場合()ジョブは独自のプロセスグループにあるため、Ctrl+を押してもC影響を受けません。
プログラムtimeout
は自分自身を独自のプロセスグループに配置します。ソースコードから:
/* Ensure we're in our own group so all subprocesses can be killed.
Note we don't just put the child in a separate group as
then we would need to worry about foreground and background groups
and propagating signals between them. */
setpgid (0, 0);
タイムアウトが発生した場合は、timeout
そのグループが属するプロセスグループを終了する簡単な回避策を実行してください。自分を別のプロセスグループに入れたので、親プロセスはそのグループに属しません。ここでプロセスグループを使用すると、サブアプリケーションが複数のプロセスに分岐した場合、すべてのプロセスがシグナルを受け取ります。
timeout
コマンドラインから直接実行して+を押すと、子CtrlプロセスはC結果SIGINTを受け取りますが、親の対話型シェルはそうではありません。スクリプトから呼び出されると、スクリプトを実行しているシェルだけがシグナルを受け取ります。別のプロセスグループにあるため、信号を受信しません。timeout
timeout
timeout
timeout
組み込み関数を使用して、シェルスクリプトでシグナルハンドラを設定できますtrap
。残念ながら、それほど単純ではありません。考えてみてください:
#!/bin/sh
trap 'echo Interrupted at $(date)' INT
date
timeout 5 sleep 10
date
Ctrl2秒後に+を押すと、Cまだ5秒待ってから「Interrupted」メッセージが表示されます。これは、バックグラウンドジョブがアクティブな間にシェルがトラップコードを実行しないためです。
この問題を解決するには、バックグラウンドでタスクを実行してください。シグナルハンドラでは、kill
シグナルをtimeout
プロセスグループに転送するための呼び出しが行われます。
#!/bin/sh
trap 'kill -INT -$pid' INT
timeout 5 sleep 10 &
pid=$!
wait $pid
答え2
Gilesが提供した素晴らしい答えに基づいて構築されました。 timeout コマンドには前景オプションがあります。 CTRL+C を使用すると、timeout コマンドが終了します。
#!/bin/sh
trap 'echo caught interrupt and exiting;exit' INT
date
timeout --foreground 5 sleep 10
date
答え3
デフォルトでは、Ctrl+は信号をC送り、+Zは信号を送ります。SIGINT
CtrlSIGTSTP
SIGTSTP
プロセスを停止するとSIGCONT
続行します。
これは、コマンドラインから分岐したフォアグラウンドプロセスで機能します。
プロセスがバックグラウンドプロセスの場合は、その信号をプロセスに別の方法で送信する必要があります。kill
そうします。理論的には、終了時に "-"演算子は子プロセスにもシグナルを送信する必要がありますが、期待どおりに動作することはほとんどありません。
追加資料:Unix信号