web-dev-qa-db-ja.com

Linuxで2つの名前付きパイプを1つの入力ストリームに結合する方法

パイプ(|)Linuxの機能標準入力を1つまたは複数の出力ストリームにフォワードチェーンできます。

teeを使用して、出力を分割してサブプロセスを分離できます。

2つの入力ストリームを結合するコマンドはありますか?

これについてどうすればいいですか? diffはどのように機能しますか?

66
Brad

個人的には、私のお気に入り(ほとんどのLinuxディストリビューションで標準となっているbashなどが必要です)

詳細は、2つの出力内容とそれらをどのようにマージするかによって大きく異なります。

コマンド1とコマンド2の出力後の内容:

_cat <(command1) <(command2) > outputfile
_

または、両方のコマンドが、並べて表示したい同じデータの代替バージョンを出力する場合(私はこれをsnmpwalkで使用しました。一方の側の番号ともう一方の側のMIB名):

_paste <(command1) <(command2) > outputfile
_

または、2つの類似したコマンドの出力を比較する場合(2つの異なるディレクトリでの検索など)

_diff <(command1) <(command2) > outputfile
_

または、それらが何らかの並べ替えられた出力である場合は、それらをマージします。

_sort -m <(command1) <(command2) > outputfile
_

または、両方のコマンドを一度に実行します(ただし、少しスクランブルをかけることができます)。

_cat <(command1 & command2) > outputfile
_

<()演算子は、各コマンドの名前付きパイプ(または/ dev/fd)をセットアップし、そのコマンドの出力を名前付きパイプ(または/ dev/fdファイルハンドル参照)にパイプして、コマンドラインに名前を渡します。 >()に相当するものがあります。たとえば、command0 | tee >(command1) >(command2) >(command3) | command4を使用すると、1つのコマンドの出力を他の4つのコマンドに同時に送信できます。

109
freiheit

ゴリラが示すように、catを使用して2つの蒸気を別の蒸気に追加できます。

FIFOを作成し、コマンドの出力をそのFIFOに送信し、他のプログラムでFIFOから読み取ることもできます。

mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo

ファイルの書き込みまたは読み取りのみを行うプログラム、またはstdout/fileのみを出力するプログラムと、他のファイルのみをサポートするプログラムとの混合に特に役立ちます。

16
Chris S
(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output

/tmp/p1および/tmp/p2は入力パイプですが、/tmp/outputは出力です。

9
gorilla

私はこれのために特別なプログラムを作成しました: fdlinecombine

複数のパイプ(通常はプログラム出力)を読み取り、それらをstdoutに行ごとに書き込みます(セパレーターをオーバーライドすることもできます)。

5
Vi.

ここで注意してください。それらをカットするだけでは、望ましくない方法で結果が混在することになります。たとえば、それらがログファイルである場合、一方の行からもう一方の行の途中まで挿入された行が本当に望ましくない場合があります。それでいいのなら

テール-f/tmp/p1/tmp/p2>/tmp/output

働くでしょう。それがでない場合は、行のバッファリングを行い、完全な行のみを出力するものを見つける必要があります。 Syslogはこれを行いますが、他に何ができるかわかりません。

編集:バッファリングされていない読み取りと名前付きパイプの最適化:

/ tmp/p1、/ tmp/p2、/ tmp/p3を「mkfifo/tmp/p[〜#〜] n [〜#〜]によって作成された名前付きパイプと見なす」

テール-q -f/tmp/p1/tmp/p2 | awk '{print $ 0> "/ tmp/p3"; close( "/ tmp/p3"); fflush();} '&

このようにして、名前付きパイプ「/ tmp/p3」の出力を読み取ることができますnbuffered by:

テール-f/tmp/p3

小さなバグがあり、最初の入力パイプ/ tmp/p1を「初期化」する必要があります。

echo -n>/tmp/p1

tailを実行するには、最初に2番目のパイプ/ tmp/p2からの入力を受け入れ、何かが/ tmp/p1に到達するまで待機しません。これは当てはまらない場合があります。確信がある場合は、/ tmp/p1が最初に入力を受け取ります。

また、tailがファイル名に関する不要な情報を出力しないようにするには、-qオプションが必要です。

3
pjz

私がこれに使用した本当にクールなコマンドはtpipeです。それほど一般的ではないので、コンパイルする必要があるかもしれません。それはあなたが話していることを正確に行うのに本当に素晴らしいです、そしてそれは私が通常それをインストールするのでとてもきれいです。 manページはこちら http://linux.die.net/man/1/tpipe です。現在リストされているダウンロードはこのアーカイブにあります http://www.eurogaran.com/downloads/tpipe/

このように使われています

## Reinject sub-pipeline stdout into standard output:
$ pipeline1 | tpipe "pipeline2" | pipeline3
3
J. M. Becker

これを行うのに最適なプログラムは lmerge です。 freihartの回答とは異なり、それは行指向であるため、2つのコマンドの出力は互いに干渉しません。他のソリューションとは異なり、入力をかなりマージするため、出力を支配するコマンドはありません。例えば:

$ lmerge <(yes foo) <(yes bar) | head -n 4

以下の出力を提供します。

foo
bar
foo
bar
1
Rian Hunter