一時ファイルなしの2つのプログラムからの出力の差分


145

私も番組を持っていると言うaと、b私が実行できることを./a./b

最初に一時ファイルに書き込むことなく、出力を比較することはできますか?


回答:


211

<(command)あるコマンドの出力をファイル名のように別のプログラムに渡すために使用します。bashはプログラムの出力をパイプにパイプし、ファイル名/dev/fd/63を外部コマンドに渡します。

diff <(./a) <(./b)

同様>(command)何かコマンドにパイプしたい場合にも使用できます。

これは、Bashのmanページでは「Process Substitution」と呼ばれています。


1
注意すべき1つの欠点は、。/ aまたは./bが失敗した場合、呼び出し元がそれを見つけられないことです。
アレクサンダーポグレブニャック

5
OPは質問bashにタグを付けましたが、念のため、これは他のシェルでは機能しません。これは、Posixユーティリティ標準のbash拡張機能です。
DigitalRoss 2010

5
この解決策をJavaプログラムで試したところ、次のエラーが発生しました-bash: syntax error near unexpected token ('。括弧なしでもう一度試してみました-bash: java: No such file or directory。コマンドにパラメーターがある場合は機能しませんか?
スタイル

1
@DigitalRoss-エイリアスを使用してソリューションを他のシェルに拡張できます。tcshでは、次の醜さは機能します alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'。(次に、例:diffcmd "ls" "ls -a")。
ポールリンチ

グーグルの外をさまよっている人にとっては、これはzshでも動作します。(また、を呼び出すものに入力をフィードする必要がある場合fseek、zshは=(./a)同じように使用でき<(./a)ますが、フードの下で一時ファイルを使用します。一時ファイルはzshによって削除されます。)
ssokolow

26

両方の答えに加えて、並べて比較を表示したい場合は、次を使用しますvimdiff

vimdiff <(./a) <(./b)

このようなもの:

ここに画像の説明を入力してください


vimdiff美しく、スマートでインタラクティブな違い比較ビューを作成します。vimほとんどのシステムではパッケージに付属しているようです。
TimVisée2017

vimdiffは、異なる行だけでなく、異なる特定のテキストフラグメントも示しています。
アントンTarasenko


15

好奇心旺盛な方のために、これはFishシェルを使用してプロセスを置き換える方法です。

バッシュ:

diff <(./a) <(./b)

魚:

diff (./a | psub) (./b | psub)

残念ながら、魚への実装は現在不十分です。魚はハングするか、ディスク上の一時ファイルを使用します。コマンドからの出力にpsubを使用することもできません。


これは現在、魚では正しく機能しません。プログラムの出力が1つのBUFSIZより大きい場合、コマンドはハングします。(または、魚は実際にはディスク上の一時ファイルを使用するだけです)
Evan Benn

7

すでに良い答えにもう少し追加(助けてくれました!):

コマンドはdocker、ヘルプをSTD_ERRファイル記述子2に出力します。

私はかどうかを確認したかったdocker attachdocker attach --help同じ出力を与えました

$ docker attach

$ docker attach --help

これら2つのコマンドを入力しただけで、次のことを行いました。

$ diff <(!-2 2>&1) <(!! 2>&1)

!! これは!-1と同じです。つまり、このコマンドの前にコマンド1を実行します-最後のコマンド

!-2は、このコマンドの2つ前にコマンドを実行することを意味します

2>&1は、file_descriptor 2出力(STD_ERR)をfile_descriptor 1出力(STD_OUT)と同じ場所に送信することを意味します

これが役立つことを願っています。


0

zshの場合、を使用=(command)すると、一時ファイルが自動的に作成され=(command)、ファイル自体のパスに置き換えられます。通常のプロセス置換で$(command)は、コマンドの出力に置き換えられます。

このzsh機能は非常に便利であり、Beyond Compareなどのdiffツールを使用して2つのコマンドの出力を比較するためにこのように使用できます。

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

ビヨンドのために、あなたが使用しなければならないことに注意してください比較bcomp上記(代わりのためbcompare以来)bcomp進水比較して待機し、それが完了するのを。を使用するとbcompare、比較が開始され、コマンドの出力を保存するために作成された一時ファイルが消えるため、すぐに終了します。

詳細はこちら:http : //zsh.sourceforge.net/Intro/intro_7.html

これにも注意してください:

シェルは一時ファイルを作成し、コマンドが完了するとそれを削除することに注意してください。

そして、の間の差であるとして、次の$(...)=(...)

zshのマニュアルページを読むと、<(...)が=(...)に類似した別の形式のプロセス置換であることがわかります。2つの間に重要な違いがあります。<(...)の場合、シェルはファイルの代わりに名前付きパイプ(FIFO)を作成します。ファイルシステムがいっぱいにならないため、これはより良い方法です。ただし、すべての場合で機能するわけではありません。実際、上記の例で=(...)を<(...)に置き換えた場合、fgrep -f <(...)を除いて、すべてが機能しなくなります。パイプを編集したり、メールフォルダーとして開いたりすることはできません。ただし、fgrepでは、パイプから単語のリストを読み取ることは問題ありません。foo |ので、なぜdiff <(foo)barが機能しないのか疑問に思われるかもしれません。diff-バーは機能します。これは、diffが引数の1つが-であることに気付いた場合に一時ファイルを作成し、標準入力を一時ファイルにコピーするためです。

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