web-dev-qa-db-ja.com

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

./a./bで実行できるプログラムabもあるとします。

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

139
Verhogen

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

_diff <(./a) <(./b)
_

同様に、何かをパイプする場合は>(command)を使用できますintoコマンド。

これは、Bashのマニュアルページで「プロセスの置換」と呼ばれます。

203
John Kugelman

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

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

このようなもの:

enter image description here

25
brokenfoot

1つのオプションは、 名前付きパイプ(FIFO) を使用することです。

mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo

...しかし John Kugelmanの解 はずっときれいです。

20
martin clayton

興味のある方は、これが Fish Shell を使用してプロセス置換を実行する方法です:

バッシュ:

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

魚:

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

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

14
James McMahon

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

コマンドdockerは、そのヘルプを_STD_ERR_(つまり、ファイル記述子2)に出力します

_docker attach_と_docker 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)と同じ場所に送信することを意味します

これが何らかの役に立つことを願っています。

7
darrenthatcher

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

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

_bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)
_

Beyond Compareの場合、bcompが比較を開始し、完了するまでwaitsになるため、bcompareの代わりにbcompを使用する必要があることに注意してください。 bcompareを使用すると、比較が開始され、すぐに終了します。これにより、コマンドの出力を保存するために作成された一時ファイルが消えます。

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

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

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

$(...)=(...)の違いは次のとおりです。

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

0
Ashutosh Jindal