コマンドの出力(例:diff)を変数に保存する方法

コマンドの出力(例:diff)を変数に保存する方法

出力があるかどうかをテストしたいdiff(ファイルが同じかどうかをテストする)し、ない場合はテスト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直接変数に保存できるかどうかです。

答え1

これは機能します:

diff "./helloworld$x.out" "./output/helloworld$x.out" >/dev/nullの場合;
    echo "$x が合格しました";
それ以外
    echo "$x が失敗しました";
フィ

の代わりに変数を使用する場合は、ブランチechoを削除できますelse。 の前に変数を false に設定してif、コードを 2 行節約します。

実際に結果を変数に格納したい場合は、次のようにします。

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

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

rinzwind@discworld:~$ タッチ 1
rinzwind@discworld:~$ タッチ 2
rinzwind@discworld:~$ さらにテスト
diff 1 2 >/dev/nullの場合
    echo "$x が合格しました";
それ以外
    echo "$x が失敗しました";
フィ
rinzwind@discworld:~$ ./test
合格した

rinzwind@discworld:~$ vi 2
rinzwind@discworld:~$ 以上 2
2
rinzwind@discworld:~$ ./test
失敗した

の部分では>/dev/null>/dev/null 2>&1出力を に送信し>/dev/null2>&1 標準エラーを同じファイルに送信します (&1は「最初のパラメータを使用する」という意味です)。このコマンドの前にあります (つまり、 も使用されます/dev/null)。

補足:sdiff並べてdiffリストを表示します:

差分 1 2
1 1
2 2
3 3
4 4
5 5
7 7
                                  > 8
9 9
10 10

答え2

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" ]推奨されます。

答え3

a) コマンド1の出力は次のようにキャッチできる。

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

答え4

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

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi

関連情報