bashが「>>()」を処理する方法


9

出力のリダイレクトとプロセスの置換を実験しているときに、次のコマンドとその結果の出力を偶然見つけました。

    me @ elem:〜$ echo foo>>(cat); エコーバー
    バー
    me @ elem:〜$ foo

(はい、最後の空の改行は意図的なものです。)

つまり、echoのバーをbashし、通常のプロンプトを表示し、echoのfoo、echoは改行、カーソルをそこに残します。もう一度Enterキーを押すと、プロンプトが新しい行に出力され、カーソルはそのあとに表示されます(空のコマンドラインでEnterキーを押すと期待どおり)。

私はそれがファイル記述子にfooを書き込み、猫がそれを読み取り、2番目のエコーエコーのバーであるエコーのfooを読み取り、その後コマンドプロンプトに戻ることを期待していました。しかし、明らかにそうではありません。

誰かが何が起こっているのか説明してもらえますか?


私はこれに関する答えを探すことを提案したいと思います:unix.stackexchange.com/questions/182800/…それは二重のリダイレクトを説明し、異なる結果で終了する理由を説明します。ムルとマイケル・ホーマーの両方。
ノータイム

Bourne Againシェルの一部のバージョンで、プロンプトの後にプロセス置換の出力が表示される(そして状況によってはまったく表示されない)理由を明確に扱う質問については、unix.stackexchange.com/questions/471987を参照してください。
JdeBP 2018

回答:


9

タイミングによっては、プロンプトのfoobar、後bar、またはプロンプトの後に表示される場合があります。一定のタイミングを得るために少し遅延を追加します。

$ echo foo > >(sleep 1; cat); echo bar; sleep 2 
bar
foo
$

barすぐに表示され、次にfoo1秒後に表示され、次のプロンプトがさらに1秒後に表示されます。

何が起こっているのかというと、bashはプロセス置換をバックグラウンドで実行しています。

  1. メインのbashプロセスは、サブシェルを実行して実行しsleep 1; cat、それにパイプを設定します。
  2. メインのbashプロセスが実行されecho fooます。これはパイプのバッファーをいっぱいにしないため、echoコマンドはブロックせずに終了します。
  3. メインのbashプロセスが実行されecho barます。
  4. メインのbashプロセスがコマンドを起動しsleep 2ます。
  5. その間、サブシェルはコマンドを起動していsleep 1ます。
  6. 約1秒後sleep 1、サブプロセスに戻ります。サブプロセスは実行に進みcatます。
  7. cat 入力を出力(画面に表示される)にコピーして戻ります。
  8. サブシェルはそのジョブを終了し、終了します。
  9. さらに1秒後にsleep 2戻ります。メインシェルプロセスの実行が終了し、次のプロンプトが表示されます。

3

その効果を得るためにプロセスを置き換える必要はありません。これを試して:

( echo foo | cat & )

同じ理由で、同じ結果が得られます(bar;を付けずに、それを演習として残します)。どちらの場合も、catはバックグラウンドタスクとして開始されます。ここの私の行では、それは明白です。プロセス置換の場合、それはまた明白です-それは名前ファイル記述子に接続された別個のプロセスです-しかし、それはおそらくそれほど明白ではありません。

子プロセスはbash、次のプロンプトを出力する前に終了する必要はありません。また、その出力はバッファリングされるため、終了するまで何も出力しません。その時点で、bashは$stderrに印刷されたばかりで、バックグラウンドプロセスは印刷fooと改行の後に終了します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.