前のコマンドがSTDOUTに書き込んでいる間に別のコマンドをSTDINに入力しても安全ですか?


21

おそらくこれは以前に回答されたのでしょうが、別の回答へのリンクを歓迎します...

bash次のようなシェルコマンドを(シェルで)実行すると:

make

その後からの出力は、一方でmakeからでスクロールしているSTDOUTmakeI型の場合は、コマンドmake checkキーを押しenter最初のコマンドの前には、とき、実行を終了するmakeコマンドが最終的に次のコマンドが終了しmake check、右アップし、実行を選択します。

私の質問は単純です:

  1. これは危険ですか?
  2. この種のラッシュタイピングにより、予期しない動作が発生する可能性はありますか?
  3. なぜこれが機能するのですか?

2
1.そうでないことを願っています...何年もこれをやっています!
ジョンWHスミス

回答:


20

Unixは全二重であるため、動作します。リッチーが「UNIXタイムシェアリングシステム:回顧展」で述べたように:

些細なことのように思えますが、慣れると驚くべき違いを生むのは、全二重ターミナルI / Oと先読みです。プログラムは通常、単一の文字ではなく行の観点からユーザーと通信しますが、全二重端末I / Oは、システムが文字を失ったり、文字化けする心配なく、いつでも入力できることを意味します。先読みを使用すると、すべての行に対する応答を待つ必要はありません。文書を入力するタイピストは、新しい行を開始する前に一時停止しなければならないことに非常にイライラします。言いたいことを知っている人なら誰でも、情報を全速力ではなくビットごとに入力しなければならない場合、反応の遅さは心理的に拡大します。

[引用終了]

そうは言っても、先行入力を食いつぶしたり破棄したりする最新のプログラムがいくつかあります。sshapt-getは2つの例です。実行中に先に入力すると、入力の最初の部分が消えていることがあります。それはおそらく問題になるでしょう。

ssh remotehost do something that takes 20 seconds
mail bob
Dan has retired. Feel free to save any important files and then do
# ssh exits here, discarding the previous 2 lines
rm -fr *
.

bash fork()sとexecsコマンドの後、最初のコマンドはまだSTDINbashシェルにアタッチされていますか?答えはノーだと思われますが、bashは次のコマンドのためにバッファリングしているようです。あれは正しいですか?
111 ---

シェルにコマンドの標準入力をリダイレクトするように指示しない限り、コマンドはシェルと同じ標準入力を持ちます。入力したものはすべて、それを読み取る最初のプロセスによって読み取られます。シェルは、コマンドの実行中に意図的に何も読み取ろうとせず、コマンドが停止するまで待機します。を使用してコマンドをバックグラウンドで実行すると、事態はさらに複雑になります&
マークプロトニック

ではSTDIN、FIFO方式で処理されますか?そして、私はbashの子プロセスが明示的に継承されたファイルハンドルを閉じない限り、追加の型から読み取るSTDINことができると思いますか?
111 ---

はい、すべての端末入力はFIFOで処理されます。2番目の質問を理解できません。子プロセス-シェルが呼び出したコマンド-は通常、そのstdinを明示的に閉じませ。シェルは邪魔にならず、コマンドに必要なすべてを読み取らせます。その後、子は停止し、シェルは読み取りを再開します。
マークプロトニック

ええ、あなたは私のフォローアップの質問の両方に非常にはっきりと答えました、ありがとう!
111 ---

12

あなたが見ている基本的な振る舞いは、入力が読み取られるまでどこかにバッファに置かれていることです(十分に入力すると、最終的にバッファがいっぱいになり、何かが失われますが、それは多くの入力です)。makeによって実行されるほとんどのものはSTDINから読み取られないため、バッファーに残ります。

危険なのは、間違ったコマンドが入力を読み取ることです。たとえば、makeプロンプトを表示することを決定したものを呼び出すと、次のコマンドを回答として読み取ることがあります。もちろん、それがどれほど危険かはコマンド次第です。(すべての入力を最初にフラッシュし、以前の入力を破棄することもできます。)

Makefileで一般的に使用されるコマンドの1つにTeXがあります。エラーが発生した場合(およびユーザーにプロンプ​​トを表示しないフラグが設定されていない場合)、続行する方法を確認します。

より良いオプションは、おそらく実行することですmake && make check


8
  1. まあ、やや明らかに、最初のコマンド(make例では)が正常に完了したことに依存する2番目のコマンドを実行しないでください。たとえばmake foo Enter> ./foo Enter 、問題が発生する可能性があります。make && make check2番目のコマンドは、最初のコマンドが成功した場合にのみ実行されるなど、タイピングの習慣を身に付けたい場合があります。
  2. 理論的には、最初のコマンド(プロセス)が2番目のコマンドの一部を読み取ったり、そうでなければ端末入力バッファから削除したりする可能性があります。の最初の6文字を食べた場合、おそらくシステムに存在しないmake checkコマンドを実行することになりheckます(ただし、厄介なものになる可能性があります)。最初のコマンドが、あなたが知っていて信頼している良性のものである場合、私はすぐに問題を見つけません。
  3. どのように/なぜ機能しますか?システムはキーボード入力をバッファリングします。それは少し電子メールに似ています:短い時間で5つのメッセージを送信することができ、彼らは彼の受信トレイに座って、彼がそれらを読むのを待ちます。同様に、最初のコマンドがキーボードから読み取られていない限り、入力したコマンドは座って、シェルがそれらを読み取れるまで待機します。バッファリングできる「先行入力」の量には制限がありますが、通常は数百文字(数千文字ではない場合)です。

2
ポイント1には、コマンドが無関係であるlsと想像してくださいmount。バッファリングされた入力の処理方法を理解しようとしています。答えてくれてありがとう。
111 ---
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.