コマンドが終了するたびに自動的に再実行したいので、次のようなコマンドを実行しました。
while [ 1 ]; do COMMAND; done;
しかし、私はループを止めることができないならばCtrl-cそれはちょうど殺すようCOMMAND
ループ全体をしていません。
同様のことをどのようにして達成できますか?端末を閉じることなく停止できますか?
コマンドが終了するたびに自動的に再実行したいので、次のようなコマンドを実行しました。
while [ 1 ]; do COMMAND; done;
しかし、私はループを止めることができないならばCtrl-cそれはちょうど殺すようCOMMAND
ループ全体をしていません。
同様のことをどのようにして達成できますか?端末を閉じることなく停止できますか?
回答:
コマンドの終了ステータスを確認してください。コマンドがシグナルで終了した場合、終了コードは128 +シグナル番号になります。bashのGNUオンラインドキュメントから:
シェルの目的のために、ゼロの終了ステータスで終了するコマンドは成功しました。ゼロ以外の終了ステータスは失敗を示します。この一見反直感的なスキームが使用されているため、成功を示す明確に定義された方法と、さまざまな失敗モードを示すさまざまな方法があります。番号がNである致命的なシグナルでコマンドが終了すると、Bashは値128 + Nを終了ステータスとして使用します。
POSIXは、シグナルで終了するコマンドの値が128より大きいことも指定していますが、GNUのように正確な値を指定していないようです:
シグナルを受信したために終了したコマンドの終了ステータスは、128を超えると報告されます。
たとえば、control-Cでコマンドを中断した場合、終了コードは130になります。これは、UNIXシステムではSIGINTがシグナル2であるためです。そう:
while [ 1 ]; do COMMAND; test $? -gt 128 && break; done
paplay alert.ogg
で動作していません。おそらくpaplay
信号を処理するためでしょうか?
無限ループをスクリプトに入れて、そこで信号を処理するのが最善かもしれません。これが基本的な出発点です。必要に応じて変更することをお勧めします。スクリプトは- (または)trap
をキャッチするために使用し、コマンドを終了し(ここではテストとして使用しました)、終了します。ctrlcSIGTERM
sleep
cleanup ()
{
kill -s SIGTERM $!
exit 0
}
trap cleanup SIGINT SIGTERM
while [ 1 ]
do
sleep 60 &
wait $!
done
trap "exit 0" SIGINT SIGTERM; while true; do netcat -l -p 3000; done
私は一般的に押さえるだけCtrl-Cです。遅かれ早かれ、の間に登録されCOMMAND
、while
ループが終了します。おそらくもっと良い方法があります。
paplay
、1sファイルのような特定のコマンドでは失敗します。
なぜ単純に、
while [ 1 ]; do COMMAND || break; done;
または、スクリプトで使用する場合、
#!/bin/bash
while [ 1 ]; do
# ctrl+c terminates COMMAND and exits the while loop
# (assuming COMMAND responds to ctrl+c)
COMMAND || break
done;
while :
無限ループを作成し、書き込みを保存します [ 1 ]
while :; do COMMAND; done &
これにより、PIDが出力されます。を使用してプロンプトを終了するとctrl+d
、バックグラウンドジョブは終了せず、後でどこからでもジョブを強制終了できます。kill PID
PIDを追跡できなくなった場合、pstree -pa $USER
またはpgrep -fl '.*PROCESS.*'
を使用してPID を見つけることができます