以下のコマンドを実行しようとしています。
cat numbers.txt | sort < words.txt
上記のコマンドには、 sort コマンドの入力ストリームを供給する cat コマンドのパイプがあります。しかし同時に、sort コマンドの入力ストリームも word.txt ファイルにリダイレクトされます。コマンドを実行すると、word.txtのデータがsortコマンドによってソートされ、端末に再表示されることがわかりました。
この場合、シェルがパイプとリダイレクトをどのように処理するのかわかりません。コマンドが2つの異なるソースからの入力ストリームを受け入れることができるかどうか。内部的にどのように動作するかについての私の考えは、リダイレクトとパイプがコマンドに沿って左から右に処理されるため、catコマンドの出力ストリームが最初にsortコマンドの入力ストリームとして使用されることです。ただし、sortコマンドはこのパイプの後に別の入力ストリームリダイレクトを提供するため、sortコマンドの入力ストリームはword.txtに接続されます。したがって、Words.txt のデータは、コマンドが実行されたときにのみ sort コマンドに到達します。
また、次のコマンドが実行されない理由もあります。追加のリダイレクトによるオーバーライドでリダイレクトを変更しました。
cat numbers.txt | sort << words.txt
一つある質問部分はこれに似ていますが、シェルがパイプとリダイレクトをどのように処理するかはよく理解できません。
答え1
リダイレクトは左から右に処理されます。Bashでパイプに続く(実際にはすべてのPOSIXシェル)。存在する
cat numbers.txt | sort < words.txt
シェルは最初にsort
(将来の)標準入力をそれが出てくるパイプに設定し、次に処理時に読み取るようにcat
変更< words.txt
しますwords.txt
。
<<
区切り文字を開始します。
cat numbers.txt | sort << words.txt
「words.txt」(コマンドで指定された入力終了タグなので)が表示されるのを待ちます。よりシェルの制御およびリダイレクト演算子は何ですか?
答え2
コマンドが2つの異なるソースからの入力ストリームを受け入れることができるかどうか。
いいえ。入力ストリームは実際に他の人が渡したファイル記述子にすぎません。ファイル内にファイルが1つしかないかのように、複数のストリームをマージすることはできません。
cat numbers.txt | sort < words.txt
BTWはcat
con enateの略ですcat
。文字通り、コマンドラインで指定されたすべてのファイルを出力ストリームにリンクします。
cat numbers.txt words.txt | sort
働くもちろん、sort
複数のファイル自体を並べ替えることもできるので、sort numbers.txt words.txt
効果は同じです。
しかし、質問はもっと一般的なようです。
複数のファイルとストリームがある場合は、どのように1つの出力にリンクしますか?
さて、最新のシェルはあなたが望むことをします(少なくともbashとzshはします)。
cat file1 <(some program that generates output) <(echo "foo bar") file2 | sort
これらのシェルには、<(…)
「入力ファイル名として渡された一時パイプを作成する」機能があります。もちろん、非常に簡単なサブシェル方法もあります。
( cat file1; some program that generates output; echo "foo bar"; cat file2 ) | sort
同じ効果があります。 (そこにはい実行並列性の違い。cat <(sleep 2; echo hello) <(sleep 2; echo world)
実行には合計2秒かかります(sleep 2; echo hello; sleep 2; echo world)
。 )