- ベストアンサー
シェルのリダイレクトとパイプについて
シェルのリダイレクトとパイプについての質問です. リダイレクトでコマンドの標準出力をファイルに指定した後に, パイプを置いて,もう一つコマンドを並べたとき, 後の方のコマンドの標準入力はどうなるのでしょうか? 例えば, ls >outfile |cat ならば, catの標準入力には,何も入ってこないと思うのですが, これを実行すると,lsの結果がoutfileに書き込まれ, 次のプロンプトが表示されます. 普通,catを引数なしで実行すると, EOFが入力されるまで,入力待ちになると思うのですが, こうならないのは,シェルがcatの標準入力にEOFを入力したからだと 考えていいのでしょうか. よろしくお願いします. (質問の意味が分かりにくければご指摘下さい.)
- みんなの回答 (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以外では上記と異なる場合があります。
その他の回答 (1)
- anmochi
- ベストアンサー率65% (1332/2045)
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ではリダイレクトが優先されました。
お礼
理解できました. cshとbashでの違いも参考になりました. 有り難うございます.
お礼
>パイプ処理の順序としては、細かい説明は省きますが、パイプが作られ、次にプロセスが作られ、各プロセスでリダイレクトの処理が行われ、最後にそれぞれプログラムが起動されます。 とても参考になりました. (ls ; echo "ls status=$?" >&2 ) | cat < infile という方法も教えていただき有り難うございます.