当前位置: 首页>>技术教程>>正文


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/article/12017.html,未经允许,请勿转载。