複数の標準入力?どうやって?


36

このコマンドラインの投稿から:

$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)

複数の標準入力のように見えますが、--- Linux Porgrammingコースを正しく覚えていれば-これは不可能です。定義により、標準入力は1つのストリームであると考えました。

おそらくこれはstdinと関係があるのでしょうか?誰かがこれを私に説明できますか?おそらくドキュメントへのリンクを提供してください。

ボーナス:スクリプトはこれらの複数のストリームをどのように処理しますか?誰かがPythonまたはPerlの例を提供できれば、それは非常に役立ちます。


1
良い質問。知らない場合は、unix / linux Q&Aサイト:unix.stackexchange.com
Matt Ellen


注:Bashでは<(…)、; Zshプロセスの置換構文は=(…)です。
カミル・マチオロフスキー

回答:


27

これは複数の標準入力ではありません。これは、「プロセス・置換」と呼ばれることbash'ismある http://tldp.org/LDP/abs/html/process-sub.html

/dev/fd/something置換ごとに疑似ファイル()を作成します。とても便利です。コマンドはストリームとしてのみ読み取ることができます。つまり、fseekを使用して前後に移動することはできません。パイプのようなバイトのストリームとして読み取る必要があります。

ボーナス回答

これを使用するためにあまり多くをする必要はありません。スクリプトに関する限り、コマンドラインで有効なファイル名を取得し、他のファイルと同様にopen()することができます。他の人が言ったように、あなたは見るでしょうdiff /dev/fd/XX /dev/fd/YY。これらの擬似ファイルのいずれかでstat()を実行すると、名前付きパイプであることがわかります。パイプセマンティクスで処理する必要があります。つまり、fseek()またはftell()はありません。stat()テストを実行して、それがファイル(たとえば[ -f $1 ])かどうかを明示的に確認すると、これ壊れます-これは結局名前付きパイプとして実装されます。


bashプロセス置換の別の良いリファレンス-wiki.bash-hackers.org/syntax/expansion/proc_subst
studgeek

また、この機能の推奨される使用法は何ですか?プログラムがランダムアクセスのファイルを必要とする代わりに、ストリームを合理的に動作できる場合はいつでもサポートしますか?
masterxilo

7

<(...)ないプロセス置換を bashで。括弧内のプロセスの出力は、通常の3を超える追加のファイル記述子に送信され、そのファイル記述子に対応するファイル名が返されます。このようにして、コマンドの出力を別のコマンドに渡されるファイル名として扱うことができます。


7

1があるstdinと1 stdout プロセスごとに。通常、これらは端末に接続されますが、互いに個別にリダイレクトできます。

この例では、2つのwgetプロセスが関係しており、それぞれが独自のstdinとを取得しstdoutます。各wgetプロセスは-、に書き込みますstdout。次に、bashプロセスの置換により、プロセスが一意の疑似ファイルに接続され、そこから読み取ることができます。2つのプロセス置換により2つの異なる擬似ファイルが生成されることに注意しくださいしたがって、次のように表示されます。<(...)stdoutdiffdiff

diff /dev/fd/XX /dev/fd/YY

ここstdoutwget -q -O - URL1に接続され/dev/fd/XX、そしてstdoutwget -q -O - URL2/dev/fd/YY

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.