Cách lưu đầu ra từ lệnh (ví dụ: diff) vào một biến


21

Tôi muốn kiểm tra nếu có bất kỳ đầu ra nào từ diff(kiểm tra nếu các tệp giống nhau), nếu không có echo "Passed $x" else echo "Failed $x". Tôi đã đưa ra một số bước xen kẽ (lưu kết quả đầu ra từ diff vào một tệp sau đó đọc từ tệp)

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;

Tôi chắc chắn mã có thể được cải thiện? Câu hỏi chính là: có thể lưu đầu ra từ difftrực tiếp vào một biến không?

Câu trả lời:


18

Những công việc này:

if diff "./helloworld$x.out" "./output/helloworld$x.out"> / dev / null; sau đó
    tiếng vang "Đã qua $ x";
khác
    tiếng vang "Không thành công $ x";
fi

Nếu bạn sử dụng một biến thay vì echobạn có thể bỏ elsenhánh: đặt biến thành sai trước ifvà lưu 2 dòng mã.

Nếu bạn muốn thực sự đưa kết quả vào một biến sử dụng:

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

Bao gồm cả thử nghiệm của tôi để xem nó có thực sự hoạt động không:

rinzwind @ Discworld: ~ $ touch 1
rinzwind @ Discworld: ~ $ touch 2
rinzwind @ Discworld: ~ $ kiểm tra thêm
nếu khác 1 2> / dev / null; sau đó
    tiếng vang "Đã qua $ x";
khác
    tiếng vang "Không thành công $ x";
fi
rinzwind @ Discworld: ~ $ ./test
Thông qua 

rinzwind @ Discworld: ~ $ vi 2
rinzwind @ Discworld: ~ $ 2
2
rinzwind @ Discworld: ~ $ ./test
Thất bại 

Về >/dev/nullphần: >/dev/null 2>&1sẽ gửi đầu ra đến >/dev/null2>&1 sẽ gửi các lỗi tiêu chuẩn đến cùng một tệp ( &1có nghĩa là 'sử dụng tham số đầu tiên') trước lệnh này (vì vậy nó cũng sử dụng /dev/null).

sidenote: sdiffsẽ hiển thị diffdanh sách bên cạnh :

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

Cảm ơn nó hoạt động, nhưng tôi không hiểu những gì ... > /dev/nulllàm trong bối cảnh này. Đầu ra của diff sẽ goto / dev / null nhưng không phải là không có gì?
Jiew Meng

1
Diff sẽ xuất ra tất cả sự khác biệt giữa các tệp trên màn hình của bạn và> / dev / null đảm bảo đầu ra của lệnh được chuyển hướng đến lãng quên. Nếu if vẫn được thực hiện dựa trên đầu ra.
Rinzwind

1
Câu lệnh if kiểm tra mã thoát của lệnh diff. 0 có nghĩa là không có sự khác biệt nào được tìm thấy, trong khi 1 có nghĩa là có một hoặc nhiều sự khác biệt.
Knut Eldhuset

17

diff thậm chí có thể triệt tiêu hoàn toàn đầu ra ngoại trừ thông báo "Files / bin / bash và / bin / sh differ" bằng cách sử dụng mã bên dưới.

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

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

Nếu bạn thậm chí muốn ẩn tin nhắn đó, bạn sẽ nối thêm > /dev/nullsau lệnh diff để ẩn đầu ra của diff:

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

/dev/null là một tệp đặc biệt hoạt động như một lỗ đen, nếu bạn viết cho nó, nó sẽ biến mất, nếu bạn đọc từ nó, bạn sẽ không nhận được gì.

Lưu ý rằng bash không cần ;kết thúc dòng.

Đối với câu hỏi ban đầu, để lưu đầu ra của một chương trình trong một biến:

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

Các cách khác để kiểm tra xem một biến có trống không:

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

Nếu bạn đang sử dụng Bash, hai lệnh cuối được khuyến nghị để so sánh chuỗi. Nếu không, đầu tiên và [ -n "$output" ]được khuyến khích.


6

a) Đầu ra của lệnh1 có thể được bắt với

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

hoặc với backticks, nhưng chúng không được khuyến khích, vì bạn không thể lồng chúng và chúng có thể khó phân biệt với dấu nháy đơn, tùy thuộc vào phông chữ:

 output=`cmd1`

b) Thay vì ghi vào một tệp, sau đó đọc tệp đó, (hoặc lấy đầu ra, sau đó lặp lại), bạn sẽ sử dụng một đường ống trực tiếp:

 cmd1 > file
 cat file | cmd2 

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

=>

 cmd1 | cmd2 

nhưng trong ví dụ của bạn, bạn không quan tâm đến đầu ra, nhưng kết quả của chương trình - nó có hoạt động không?

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

Để đọc về việc sử dụng && và || tìm kiếm "phím tắt VÀ và phím tắt HOẶC".

Để giữ đầu ra sạch sẽ, bạn có thể chuyển hướng đầu ra của 'diff' sang hư không:

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

Để lấy thành công và đánh giá nó sau, bạn lưu trữ kết quả của lệnh cuối cùng trong một biến có $?:

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

3

Nếu bạn muốn biết hai tệp giống nhau hay khác nhau (nhưng không quan tâm sự khác biệt thực sự là gì), cmpthì phù hợp hơn.

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.