.c
ファイルとそれに対応する実行可能ファイル(fooとしましょう)があり、stdinから入力を受け取り、/bin/sh
をsys呼び出しするとします。次のように、この実行可能ファイルに入力をフィードします。
python -c "<some script to feed input>" | ./foo
Fooによって呼び出されたシェルがすぐに閉じて、fooが終了することを確認しました。ただし、IRCの誰かが、次のように実行することをお勧めします。
(python -c "<some script to feed input>"; cat) | ./foo
./foo
によって呼び出されたサブシェルを引き続き実行します。ここで何が起こっているのか知りたいのですが。
私の推測:最初のケースでは、pythonスクリプトのstdoutは、完了するとすぐに閉じますか?したがって、EOFをプロセスのstdinに送信します./foo
終了./foo
?しかし、sys呼び出しは、./foo
が終了しない原因となるブロック呼び出しである必要があるため、私には意味がありません。誤った理解を修正するためのヘルプとリソースへのポインタをいただければ幸いです。 。ありがとう!
「EOFを送信する」などというものはありません。読み取るデータがなくなると、ファイルの終わりに到達します。
最初のスニペットでは、Pythonスクリプトが終了すると、書き込み用にパイプを開いているプロセスはなくなります。したがって、foo
がパイプで送信されたすべてのデータの読み取りを終了すると、標準入力でファイルの終わりの状態を検出します。
2番目のスニペットでは、Pythonスクリプトが終了すると、パイプはサブシェルによって開いたままになります。したがって、foo
がPythonスクリプトによって生成されたすべてのデータの読み取りを終了した場合でも、それはさらに入力を待ち続けます。サブシェルはcat
を起動します。これは、独自の標準入力からデータを読み取って転送します。 cat
が終了すると、状況は以前と同じになります。書き込み用にパイプを開いているプロセスはなくなり、foo
は入力の最後に到達します。
read
システムコールでプロセスがブロックされた場合、そのシステムコールが返される理由はいくつかあります。
read
は正の値を返し、渡されたバッファーにそのバイト数を格納します。read
は0を返します。通常のファイルの場合、これはファイルの位置がファイルの終わりに達したときに発生します。パイプの場合、これは、ファイルを開いていた最後のプロセスが停止し、パイプのバッファーが完全に消費されたときに発生します。read
は-1を返します。