web-dev-qa-db-ja.com

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

これから commandlinefu post

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

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

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

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

37

これは複数の標準入力ではありません。これは 'Process Substitution'と呼ばれるbash主義です 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 ])thiswillbreak-これは結局名前付きパイプとして実装されます。

29
Rich Homolka

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

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

_diff /dev/fd/XX /dev/fd/YY
_

ここで、_wget -q -O - URL1_のstdoutは_/dev/fd/XX_に接続され、_wget -q -O - URL2_のstdoutは_/dev/fd/YY_に接続されます。

7
musiphil

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