當前位置: 首頁>>技術教程>>正文


bash – 如何將命令的輸出(例如 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 的輸出直接保存到變量中?

最佳回答

這有效:

if diff "./helloworld$x.out" "./output/helloworld$x.out" >/dev/null; then
    echo "Passed $x";
else
    echo "Failed $x";
fi

如果您使用變量而不是 echo,您可以刪除 else 分支:在 if 之前將變量設置為 false 並保存 2 行代碼。

如果您想將結果實際放入變量中,請使用:

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

包括我的測試,看看它是否確實有效:


rinzwind@discworld:~$ touch 1
rinzwind@discworld:~$ touch 2
rinzwind@discworld:~$ more test
if diff 1 2 >/dev/null; then
    echo "Passed $x";
else
    echo "Failed $x";
fi
rinzwind@discworld:~$ ./test
Passed 

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

>/dev/null 部分: >/dev/null 2>&1 將輸出發送到 >/dev/null 並且 2>&1 將標準錯誤發送到此命令前麵的同一文件( &1 表示“使用第一個參數”)(因此它也使用 /dev/null )。

旁注:sdiff 將顯示 side-by-side diff 列表:


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

次佳回答

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

如果您甚至想隱藏該消息,則必須在 diff 命令後附加 > /dev/null 以隱藏 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,建議使用最後兩個命令進行字符串比較。否則,建議使用第一個和 [ -n "$output" ]

第三種回答

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

第四種回答

如果你想知道兩個文件是相同的還是不同的(但不關心實際的區別是什麽),cmp 更合適。

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

參考資料

本文由Ubuntu問答整理, 博文地址: https://ubuntuqa.com/zh-tw/article/12017.html,未經允許,請勿轉載。