web-dev-qa-db-ja.com

コマンド呼び出しが成功した場合にのみ出力をリダイレクトする

コマンドの出力(この場合はdiff)をファイルにリダイレクトしたいのですが、比較しているファイルに違いがある場合のみです。たとえば、abcの3つのファイルがあるとします。ここで、abは同等ですが、acはそうではありません。

私が行った場合 diff a c > output.txtまたはdiff a b > output.txt、違いがあるかどうかに関係なく、output.txtが作成されます。 output.txtは、diffがある場合に作成されます(つまり、diffは1を返します)。

私は次のようなことをしたいと思います:

if ! diff a c > /dev/null; then
    diff a c > output.txt
fi

ただし、コマンドを2回実行する必要はありません。 I couldコマンドの内容を次のように保存します。

res=$(diff a c)
if [ $? != 0 ]; then
    echo "$res" > output.txt
fi

しかし、私はechoを「中間者」としてこれに取り入れています。これは、いくつかの問題を引き起こす可能性があります。コードを複製せずに出力がある場合にのみ、出力をリダイレクト/ファイルを作成するにはどうすればよいですか?

6
TerryA

コマンドを1回呼び出して出力をリダイレクトし、違いがない場合は出力を削除できます。

diff a c > output.txt && rm output.txt
8
Jeff Schaller

diffは、少なくともファイルが異なる場合、比較的高価なコマンドです。変更の最小セットの計算は(比較的)CPUに負荷がかかります。だから、二度やりたくないのは当然だ。

cmpは、CPUの観点からは安価です。これらのファイルが適切なサイズであると想定すると(マルチGBファイルでdiffを呼び出すことはないと思います)、パフォーマンスコストはほとんどなく、ファイルが同一の場合はさらに高速になる可能性があります。

if ! cmp -s a c; then # -s = silent, do not print results to console
    diff a c > output.txt
fi
7
derobert

一時ファイルはどうですか?

diff a c > /tmp/output.txt
if [ $? != 0 ]; then mv /tmp/output.txt /my/folder/output.txt; else rm -f /tmp/output.txt; fi

-f-i削除確認ダイアログが必要な場合。

この方法では、コマンドを2回実行するだけで、一時的な変数や、echo、printfなどの「中間者」はありません。

5
deimos