無限ループの終了

無限ループの終了

終了するたびに自動的に再度実行したいコマンドがあるので、次のようなコマンドを実行しました。

while [ 1 ]; do COMMAND; done;

Ctrl-cしかし、 as を使用してループを停止できない場合は、COMMANDループ全体ではなく、ループのみが強制終了されます。

ターミナルを閉じずに停止できる同様のことを実現するにはどうすればよいでしょうか?

答え1

ctrl+を使用すると、実行中にジョブを停止してバックグラウンドに置くことができますz。その後、次のコマンドでジョブを強制終了できます。

$ kill %1

[1]はあなたのジョブ番号です。

答え2

コマンドの終了ステータスを確認します。コマンドがシグナルによって終了した場合、終了コードは128 + シグナル番号になります。bash の GNU オンライン ドキュメント:

シェルの目的上、終了ステータスがゼロで終了するコマンドは成功です。終了ステータスがゼロ以外の場合は失敗を示します。この一見直感に反する方式が使用されるのは、成功を示す明確な方法が 1 つあり、さまざまな失敗モードを示す方法が複数あるためです。コマンドが N の番号の致命的なシグナルで終了すると、Bash は終了ステータスとして値 128+N を使用します。

POSIXでは、シグナルによって終了したコマンドの値は 128 より大きいですが、GNU のように正確な値を指定していないようです。

シグナルを受信したために終了したコマンドの終了ステータスは、128 より大きい値として報告されます。

たとえば、Ctrl + C でコマンドを中断した場合、終了コードは 130 になります。これは、SIGINT が Unix システム上のシグナル 2 であるためです。つまり、

while [ 1 ]; do COMMAND; test $? -gt 128 && break; done

答え3

無限ループをスクリプト内に入れて、そこでシグナルを処理するのがベストだと思います。基本的な出発点。 必要に応じて変更してください。スクリプトは、- (または)trapをキャッチするためにを使用し、コマンドを強制終了して (ここではテストとして使用しました) 終了します。ctrlcSIGTERMsleep

cleanup ()
{
kill -s SIGTERM $!
exit 0
}

trap cleanup SIGINT SIGTERM

while [ 1 ]
do
    sleep 60 &
    wait $!
done

答え4

bash を実行すると、-eエラーが発生すると終了します。

#!/bin/bash -e
false # returns 1
echo This won't be printed

関連情報