Bagaimana cara menyimpan output dari perintah (mis. Diff) ke dalam variabel

21

Saya ingin menguji apakah ada output dari diff(uji apakah file sama), jika tidak ada echo "Passed $x" else echo "Failed $x". Saya datang dengan beberapa langkah intermidiate (menyimpan output dari diff ke file kemudian membaca dari file)

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;

Saya yakin kode dapat ditingkatkan? Pertanyaan utama adalah: apakah mungkin untuk menyimpan output dari difflangsung ke variabel?

Jiew Meng
sumber

Jawaban:

18

Ini bekerja:

jika diff "./helloworld$x.out" "./output/helloworld$x.out"> / dev / null; kemudian
    gema "Lulus $ x";
lain
    echo "Failed $ x";
fi

Jika Anda menggunakan variabel alih-alih echoAnda bisa menjatuhkan elsebranche: setel variabel ke false sebelum ifdan simpan 2 baris kode.

Jika Anda ingin benar-benar memasukkan hasilnya ke dalam penggunaan variabel:

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

Termasuk pengujian saya untuk melihat apakah itu benar-benar berfungsi:

rinzwind @ discworld: ~ $ touch 1
rinzwind @ discworld: ~ $ touch 2
rinzwind @ discworld: ~ $ tes lagi
jika diff 1 2> / dev / null; kemudian
    gema "Lulus $ x";
lain
    echo "Failed $ x";
fi
rinzwind @ discworld: ~ $ ./test
Lulus 

rinzwind @ discworld: ~ $ vi 2
rinzwind @ discworld: ~ $ more 2
2
rinzwind @ discworld: ~ $ ./test
Gagal 

Pada >/dev/nullbagian: >/dev/null 2>&1akan mengirim output ke >/dev/nulldan 2>&1 akan mengirim kesalahan standar ke file yang sama ( &1berarti 'gunakan parameter pertama') di depan perintah ini (jadi itu juga menggunakan /dev/null).

sidenote: sdiffakan menampilkan diffdaftar berdampingan :

sdiff 1 2 
1 1
2 2
3 3
4 4
5 5
7 7
                                  > 8
9 9
10 10
Rinzwind
sumber
Terima kasih itu berhasil, tapi saya tidak mengerti apa yang ... > /dev/nullterjadi di konteks ini Output dari diff akan pergi / dev / null tetapi bukankah itu tidak ada?
Jiew Meng
1
Dif akan menampilkan semua perbedaan antara file di layar Anda dan> / dev / null memastikan output dari perintah diarahkan untuk dilupakan. Jika masih dieksekusi berdasarkan output.
Rinzwind
1
Pernyataan if memeriksa kode keluar dari perintah diff. 0 berarti tidak ada perbedaan yang ditemukan, sedangkan 1 berarti ada satu atau lebih perbedaan.
Knut Eldhuset
17

diff bahkan dapat menekan output sepenuhnya kecuali untuk pesan "File / bin / bash dan / bin / sh berbeda" menggunakan kode di bawah ini.

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

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

Jika Anda bahkan ingin menyembunyikan pesan itu, Anda harus menambahkan > /dev/nullsetelah perintah diff untuk menyembunyikan output dari diff:

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

/dev/null adalah file khusus yang bertindak sebagai lubang hitam, jika Anda menulisnya, itu akan hilang, jika Anda membacanya, Anda tidak akan mendapatkan apa-apa.

Perhatikan bahwa bash tidak perlu ;mengakhiri garis.

Adapun pertanyaan asli, untuk menyimpan output suatu program dalam variabel:

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

Cara alternatif untuk memeriksa apakah suatu variabel kosong:

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

Jika Anda menggunakan Bash, dua perintah terakhir direkomendasikan untuk perbandingan string. Kalau tidak, yang pertama dan [ -n "$output" ]dianjurkan.

Lekensteyn
sumber
6

a) Output dari command1 dapat ditangkap dengan

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

atau dengan backtick, tetapi itu tidak disarankan, karena Anda tidak dapat membuat sarang, dan mereka mungkin sulit dibedakan dari apostrof, tergantung pada font:

 output=`cmd1`

b) Alih-alih menulis ke file, dan kemudian membaca file itu, (atau mengambil output, dan kemudian menggemakannya) Anda akan menggunakan pipa langsung:

 cmd1 > file
 cat file | cmd2 

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

=>

 cmd1 | cmd2 

tetapi dalam contoh Anda, Anda tidak tertarik dengan output, tetapi hasil dari program - apakah berhasil?

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

Untuk membaca tentang penggunaan && dan || cari "shortcut AND dan shortcut OR".

Untuk menjaga output tetap bersih, Anda dapat mengarahkan output 'diff' ke tempat:

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

Untuk meraih sukses dan mengevaluasinya nanti, Anda menyimpan hasil dari perintah terakhir dalam variabel dengan $ ?:

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

Jika Anda ingin tahu apakah dua file itu sama atau berbeda (tetapi tidak peduli apa bedanya sebenarnya), cmplebih cocok.

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