私の理解は、シェルのパイプのようなものがstdinをa | b
stdoutにリダイレクトするということです。ところで試してみましたが、動作が変でした。リンクされた出力の内容を表示します。b
a
ls | less < somefile
less
ls
somefile
この現象を説明できる人はいますか?
答え1
あなたの理解は正確ではありません。パイプを介して接続されたa | b
プロセスの標準出力出力でa
標準入力のプロセスb
。コードの問題は、somefile
プロセスで追加のリダイレクトを実行することによって、b
2つの異なる方法を使用してプロセスのstdinに同時に接続することですb
。しないでください!問題は、最初に(これらの構造を通して)何を達成しようとしますか?
答え2
どのシェルを使用したのか言っていませんでした。説明した動作で判断すれば可能ですzsh
。マニュアルページを見ると、リダイレクトがどのように処理されるかがわかります。
したがって、パイプは暗黙的なリダイレクトです。
cat bar | sort <foo
cat bar foo | sort
(入力順に注意してください)と同じです。
bash
それ以外の場合は、各リダイレクトがそのファイル記述子の以前のリダイレクトを置き換えるのが一般的な動作です。
zsh
マニュアルページは続きます:
MULTIOS オプションが設定されていない場合、各リダイレクトは、対応するファイル記述子の以前のリダイレクトを置き換えます。ただし、リダイレクトされたすべてのファイルは実際に開かれるため、
echo foo > bar > baz
MULTIOSが設定されていない場合、バーは切り捨てられ、「foo」がbazに書き込まれます。
答え3
これは、特定のファイルからより少ない入力を受け取るためです。
次のように動作します
1 -> lsを実行します。パイプを使用したので、stdoutを次のコマンドのstdinにパイプします。それがまさにあなたが言うことです。
2 -> 2番目のコマンドを表示します。 <somefileより小さい。
すぐに'<'はstdinを再度ファイルに変更するようにリダイレクトします。したがって、以前の変更は「|」が失われたためです。
まあ、あなたは次のように言うことができます:lessはファイルから入力を受け取り、lsの出力とは何の関係もありません。