一時停止後にwhileループが停止するのはなぜですか?

一時停止後にwhileループが停止するのはなぜですか?

bashを使用してwhileループを一時停止し、再開後にループが停止するのはなぜですか?以下の簡単な例です。

$ while true; do echo .; sleep 1; done
.
.
^Z
[1]+  Stopped                 sleep 1
$ fg
sleep 1
$

私はシグナルについてよく知っており、これがbashの自然な動作であると思います。しかし、なぜこれが特定の方法で動作するのかをよりよく理解したいと思います。

答え1

これは複数のシェルのバグのように見えますが、期待どおりに動作します。クッシュ 93そして扱いにくい

背景:

ほとんどのシェルはメインシェル内でwhileループを実行しているようです。

ボンシェル非ログインシェルを使用して^ Zを入力すると、シェル全体が中断されます。

強く打つしばらく停止し、sleepwhileループをそのままにして、代わりに新しいシェルプロンプトを印刷します。

スプリントコマンドを一時停止できないように設定

そしてクッシュ 93、状況は非常に異なる動作します。

クッシュ 93コマンドを最初に実行すると同じことが行われますが、sleepksh93の組み込み機能と同様に、ksh93にはwhileループがデフォルトのシェルを分岐し、^ Z上昇を入力すると停止するハンドラがあります。

お持ちの場合クッシュ 93後で入力すると、fgループを実行している分岐サブプロセスが続行されます。

bashとksh93のジョブ制御メッセージを比較すると、主な違いがわかります。

強く打つレポート:

[1]+ Stopped sleep 1

しかし、クッシュ 93レポート:

^Z[1] + Stopped while true; do echo .; sleep 1; done

扱いにくい次のような動作クッシュ 93

両方のシェルに^Zを入力しない限り、1つのプロセス(デフォルトのシェル)があり、^Zを入力した後に2つのシェルプロセスがあります。

答え2

私はこの問題を議論するためにBashの共著者の一人に手紙を書き、彼の答えは次のとおりです。

これは実際にはエラーではありませんが、警告として機能します。

ここでのアイデアは、シェルコマンドとは異なる粒度単位であるプロセスを一時停止することです。プロセスが一時停止すると、シェルに戻り(ゼロ以外)、ループがテスト中のプロセスを停止したときに結果が発生し、オプションがあります。停止したプロセスを離れてループを中断または続行できます。後ろに。 Bashは、ジョブが停止したときにループから離れるように選択します(そして常に選択します)。周期を継続することを望む場合はほとんどありません。

一部の他のシェルは、シェルのコピーをフォークし、SIGTSTP によって一時停止されるとプロセスを停止するなどのタスクを実行します。 Bashはこれを行ったことがありません。給付保証よりも複雑に見えます。ただし、誰でもこのコードをパッチとして送信する場合は、変更のマージを検討します。

したがって、パッチを送信したい人がいる場合は、マニュアルページの電子メールアドレスを使用してください。

関連情報