.c
stdinからいくつかの入力を受け取り、次のようにその実行可能ファイルに入力を提供するファイルとその実行可能ファイル(fooと仮定)があるとします/bin/sh
。
python -c "<some script to feed input>" | ./foo
私はfooが呼び出したシェルがすぐに閉じてfooが終了することを観察しました。しかし、IRCの誰かが次のように提案しました。
(python -c "<some script to feed input>"; cat) | ./foo
呼び出されたサブシェルを./foo
実行し続けます。ここで何が起こっているのだろうか。
私の推測:最初の場合、Pythonスクリプトのstdoutが完了するとすぐに終了し、./foo
終了プロセスのstdinにEOFを送信します./foo
か?しかし、システムコールはブロックコールと見なされて./foo
終了しないので、これは私には理解できません。誤解を解決するための助けとリソースに関するアドバイスを聞きたいです。ありがとうございます!
ベストアンサー1
「EOF送信」のようなものはありません。読み取るデータがない場合は、ファイルの終わりに到達します。
最初のコードスニペットでPythonスクリプトが終了すると、パイプを開いているプロセスがなくなりました。したがって、foo
パイプに送信されたすべてのデータを読み取ると、標準入力がファイルの終了条件を検出します。
2番目のコードスニペットでPythonスクリプトが終了すると、パイプはまだサブシェルによって開かれます。したがって、foo
Pythonスクリプトで生成されたすべてのデータを読み取った後も、追加の入力を待ち続けます。cat
独自の標準入力からデータを読み取って渡すサブシェルが起動します。終了すると、cat
状況は以前と同じです。どのプロセスも書き込みを行うためにパイプを開けず、foo
入力端に到達します。
プロセスがread
システムコール内でブロックされると、システムコールが返される可能性がある理由はいくつかあります。
- データが利用可能な場合は、
read
正の値が返され、そのデータに渡されたバッファに対応するバイトが格納されます。 - ファイルの終わりに達すると
read
0が返されます。通常のファイルの場合、ファイルの場所がファイルの終わりに達すると、これが発生します。パイプの場合、これはファイルを開いた最後のプロセスが終了し、パイプのバッファが完全に消費されたときに発生します。 - エラーが発生すると
read
-1 が返されます。