牛、豚、鶏、どれか一つ食べられなくなるとしたら?

シェルのリダイレクトとパイプについての質問です.

リダイレクトでコマンドの標準出力をファイルに指定した後に,
パイプを置いて,もう一つコマンドを並べたとき,
後の方のコマンドの標準入力はどうなるのでしょうか?

例えば,
ls >outfile |cat
ならば,
catの標準入力には,何も入ってこないと思うのですが,
これを実行すると,lsの結果がoutfileに書き込まれ,
次のプロンプトが表示されます.
普通,catを引数なしで実行すると,
EOFが入力されるまで,入力待ちになると思うのですが,
こうならないのは,シェルがcatの標準入力にEOFを入力したからだと
考えていいのでしょうか.

よろしくお願いします.
(質問の意味が分かりにくければご指摘下さい.)

「シェルのリダイレクトとパイプについて」の質問画像

A 回答 (2件)

パイプ処理の順序としては、細かい説明は省きますが、パイプが作られ、次にプロセスが作られ、各プロセスでリダイレクトの処理が行われ、最後にそれぞれプログラムが起動されます。


リダイレクトが優先されるように見えるというのはそういうことです。

ls > outfile | cat
だと、前半の > のリダイレクト処理の時点で、パイプの入り口がcloseされます。入り口がクローズされたパイプの出口を読もうとすると、EOFが返るので、cat は終了します。これはシェルの機能と言うより、OSのパイプの機能です。

ls | cat < infile
同じく、後半のリダイレクト処理の時点で、パイプの出口がcloseされます。出口がクローズされたパイプの入り口に書き込もうとすると、SIGPIPE というシグナルが発生します。

(ls ; echo "ls status=$?" >&2 ) | cat < infile
を実行すると、
ls status=141
と表示されるはずです。141 というステータスは、プロセスがSIGPIPEで終了したと言うことです。

なお、シェルによってclose等ののタイミングが異なるようで、sh bash以外では上記と異なる場合があります。
    • good
    • 0
この回答へのお礼

>パイプ処理の順序としては、細かい説明は省きますが、パイプが作られ、次にプロセスが作られ、各プロセスでリダイレクトの処理が行われ、最後にそれぞれプログラムが起動されます。

とても参考になりました.

(ls ; echo "ls status=$?" >&2 ) | cat < infile
という方法も教えていただき有り難うございます.

お礼日時:2010/01/01 04:23

ls > outfile | cat


のcatは標準入力からの入力を一切受け取りません。考え方としてはEOFしかこなかったと考えていただいても結構ですが、正確にはそういう事(標準入力からの入力がない)です。

ls | cat < infile
こちらは
ls < infile | cat
と見比べていただけたら大体意味が分かるのではないでしょうか。ためしに
cat -n < infile | cat -n
とやってみてはどうでしょうか。

 ただ、ご存知の通りパイプとリダイレクトは「シェルの機能」です。なので、パイプやリダイレクトはこうあるべきという規定はありますが実装依存という事になります。実際に、FreeBSD 8.0-RELEASEのcshで
ls | cat < infile
としたところ、Ambigous input redirectというエラーになりました。同じくFreeBSD 8.0-RELEASEのパッケージからインストールしたbashではリダイレクトが優先されました。
    • good
    • 0
この回答へのお礼

理解できました.
cshとbashでの違いも参考になりました.
有り難うございます.

お礼日時:2010/01/01 04:22

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!