コマンド(たとえば、diff)からの出力を変数に保存する方法


21

diffnone からの出力があるかどうか(ファイルが同じかどうかをテストする)をテストしますecho "Passed $x" else echo "Failed $x"。私はいくつかの中間的なステップを考え出しました(diffからの出力をファイルに保存してから、ファイルから読み取ります)

diff "./helloworld$x.out" "./output/helloworld$x.out" > tmp.txt;
output="`cat tmp.txt`";

if [ "$output" = "" ];
  then
    echo "Passed $x";
  else
    echo "Failed $x";
  fi;

コードを改善できると確信していますか?主な質問は、出力をdiff変数に直接保存することは可能ですか?

回答:


18

これは動作します:

if diff "./helloworld$x.out" "./output/helloworld$x.out"> / dev / null; それから
    echo "Passed $ x";
他に
    echo "$ xに失敗しました";
fi

代わりに変数を使用する場合echoelsebrancheをドロップできます。変数をfalseに設定してからif2行のコードを保存します。

実際に結果を変数に入れたい場合:

some_var="$(diff "./helloworld$x.out" "./output/helloworld$x.out")"

実際に機能するかどうかを確認するためのテストを含める:

rinzwind @ discworld:〜$タッチ1
rinzwind @ discworld:〜$タッチ2
rinzwind @ discworld:〜$その他のテスト
diff 1 2> / dev / nullの場合; それから
    echo "Passed $ x";
他に
    echo "$ xに失敗しました";
fi
rinzwind @ discworld:〜$ ./test
合格 

rinzwind @ discworld:〜$ vi 2
rinzwind @ discworld:〜$ more 2
2
rinzwind @ discworld:〜$ ./test
失敗しました 

上の>/dev/null部分:>/dev/null 2>&1に出力を送信します>/dev/nullし、2>&1 同じファイル(に標準エラーを送信します&1(それはまた、使用していますので、このコマンドの前に意味「使用最初のパラメータ」) /dev/null)。

サイドノート:sdiff横並びのdiffリストを表示します:

sdiff 1 2 
1 1
2 2
3 3
4 4
5 5
7 7
                                  > 8
9 9
10 10

うまくいきました... > /dev/nullが、この文脈で何が起こるのか理解できません。diffの出力は/ dev / nullになりますが、何もありませんか?
ジウメン

1
diffは画面上のファイル間のすべての違いを出力し、> / dev / nullはコマンドの出力が忘却にリダイレクトされるようにします。ifは引き続き出力に基づいて実行されます。
リンツウィンド

1
ifステートメントは、diffコマンドの終了コードをチェックします。0は違いが見つからなかったことを意味し、1は1つ以上の違いがあったことを意味します。
クナットEldhuset

17

diff 以下のコードを使用して、「ファイル/ bin / bashと/ bin / shが異なる」メッセージを除き、出力を完全に抑制することもできます。

file1="./helloworld$x.out"
file2="./output/helloworld$x.out"

if diff -q "$file1" "$file2"; then
    echo "Passed $x"
else
    echo "Failed $x"
fi

そのメッセージを非表示にしたい場合は> /dev/null、diffコマンドの後に追加して、出力を非表示にしますdiff

if diff -q "$file1" "$file2" >/dev/null; then

/dev/null ブラックホールとして機能する特別なファイルです。書き込みを行うと消えてしまいます。読み取り中の場合は何も返されません。

bashは行;を終了する必要がないことに注意してください。

元の質問については、プログラムの出力を変数に保存するには:

file1="./helloworld$x.out"
file2="./output/helloworld$x.out"
output="$(diff -q "$file1" "$file2")"

# the quotes are mandatory, this checks whether $output is empty or not
if [ -n "$output" ]; then
    echo "Passed $x"
else
    echo "Failed $x"
fi

変数が空かどうかを確認する代替方法:

[ "$output" = "" ]
[ "$output" == "" ]
[[ "$output" == "" ]]
[[ $output == "" ]]

Bashを使用している場合、文字列の比較には最後の2つのコマンドをお勧めします。それ以外の場合は、最初のおよび[ -n "$output" ]推奨されます。


6

a)command1の出力は、でキャッチできます。

output=$(diff "helloworld$x.out" "output/helloworld$x.out") 

またはバッククティックを使用しますが、ネストすることはできません。フォントによっては、アポストロフィと区別するのが難しい場合があります。

 output=`cmd1`

b)ファイルに書き込んでからそのファイルを読み取る(または出力を取得してエコーする)代わりに、パイプを直接使用します。

 cmd1 > file
 cat file | cmd2 

 output=$(cmd1)
 echo "${output}" | cmd2 

=>

 cmd1 | cmd2 

しかし、あなたの例では、出力ではなくプログラムの結果に興味があります-それは機能しましたか?

 diff "helloworld$x.out" "output/helloworld$x.out" && echo "success" || echo "failure" 

&&および||の使用について読むには 「ショートカットANDおよびショートカットOR」を検索します。

出力をクリーンに保つために、「diff」の出力をどこにもリダイレクトできません。

 diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null && echo "success" || echo "failure" 

成功を取得して後で評価するには、最後のコマンドの結果を$?を使用して変数に保存します。

diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null
result=$?
# do something else
case $result in 
   0) echo success ;;
   *) echo failure ;;
esac

3

2つのファイルが同じであるか異なるかを知りたい場合(ただし、実際の違いを気にしないでください)は、cmpより適切です。

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.