3

我试图找出一些 Bash-foo 来检查三个不同命令的输出是否相同。我可以用几行 Bash 脚本来做到这一点,我只是想知道我想做的事情是否可以在一行中通过一些花哨的 shell I/O 重定向来实现。

我想要做的是检查 SSL 证书是否与特定的密钥和证书签名请求匹配。

命令如下所示:

openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in privateKey.key | openssl md5
openssl req -noout -modulus -in CSR.csr | openssl md5

如果密钥、证书和 csr 匹配,所有这三个命令都应该输出相同的输出,例如:“(stdin)= 95ce143e8418cf8a4f7dd718983ed4eb”。

这是一个原型:

[[ $(echo -e "blah\nblah\nblah" | uniq | wc -l) -eq 1 ]]

但我无法从那里得到最终产品。这不起作用:

[[ $(openssl x509 -noout -modulus -in certificate.crt | openssl md5 && openssl rsa -noout -modulus -in privateKey.key | openssl md5 && openssl req -noout -modulus -in CSR.csr | openssl md5 | uniq | wc -l) -eq 1 ]]

一个问题可能是我的原型从一个命令生成了所有三行输出,但实际使用&&了几次。

4

3 回答 3

5

cmp -s <( cmd1) <(cmd2) && cmp -s <( cmd1) <(cmd3)

请注意,此构造执行 cmd1 两次。

如果您需要每个 cmd 的单个 exec,更复杂的行将如下所示:

cmd1|tee >( cmp -s <(cmd2) )|cmp -s <(cmd3)

同样对于第二个,检查结果很复杂(你必须检查PIPESTATUS数组)

于 2012-06-06T00:10:41.053 回答
1

你可能的意思是

((1 == $( ( echo 1 && sleep 1; echo 1 && sleep 1) | sort -u | wc -l ) ))

但这可能更容易做到

x1=$( command1 )
x2=$( command2 )
x3=$( command3 )

if [[ $x1 == $x2 && $x2 == $x3 ]] ; then
    echo The same.
fi

编辑:这种形式也应该可以工作,但会减少存储变量的数量。

x1=$(command1)
[[ $x1 == $(command2) && $x1 == $(command3) ]] && echo match
于 2012-06-06T00:18:57.007 回答
1

问题是您仅将最后一个命令“子管道”传送到uniq. 尝试这个:

[[ $( { openssl x509 -noout -modulus -in certificate.crt | openssl md5 && openssl rsa -noout -modulus -in privateKey.key | openssl md5 && openssl req -noout -modulus -in CSR.csr | openssl md5; } | uniq | wc -l) -eq 1 ]]

花括号使三个“子管道”的行为就好像它们一起是一个命令uniq,类似于您的echo原型。

于 2012-06-06T00:36:07.083 回答