【问题标题】:Compare result of command with string in bash将命令的结果与bash中的字符串进行比较
【发布时间】:2016-08-01 04:28:16
【问题描述】:

我有一个字符串和一个命令结果,所以我想比较它们:

A="Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination"

B=$(iptables -L)

if [ "$A" == "$B"]; then
    echo "True"
else
    echo "False"
fi

但它返回False

【问题讨论】:

  • 不..这真的不行..
  • 右括号前需要一个空格,如下所示:if [ "$A" == "$B" ]; then。此外,出于兼容性原因,最好使用 single equal。喜欢if [ "$A" = "$B" ]; then
  • 有没有人知道一个好的规范副本?这是一个很常见的问题。
  • @JonathanLeffler 我们已尝试在bash tag wiki 中编制一份常见的 Bash 问题列表。它仍然需要改进,但我认为您正在寻找的典型骗子是stackoverflow.com/questions/9581064/…
  • @tripleee:看来语法错误只是问题的一部分,所以我不会把他当作骗子来关闭。但是感谢您提供有关常见 Bash 问题列表的信息。

标签: string bash variables if-statement


【解决方案1】:

这是由于使用了不同数量的空白。您可以使用以下命令找到它:

diff -u <(iptables -L) - <<EOF | cat -A
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
EOF

输出:

--- /dev/fd/63^I2016-04-11 08:59:52.663962140 +0200$
+++ -^I2016-04-11 08:59:52.666667769 +0200$
@@ -1,8 +1,8 @@$
 Chain INPUT (policy ACCEPT)$
-target     prot opt source               destination         $
+target     prot opt source               destination$
 $
 Chain FORWARD (policy ACCEPT)$
-target     prot opt source               destination         $
+target     prot opt source               destination$
 $
 Chain OUTPUT (policy ACCEPT)$
-target     prot opt source               destination         $
+target     prot opt source               destination$

你看,iptables -L 命令在destination 之后附加了空格。

要删除该空格,您可以使用 sed:

iptables -L | sed 's/[[:space:]]*$//'

如果您还修复了 Jonathan Leffler 发现的 syntax error,您的代码应该可以工作。

让我补充一下,您检查 “防火墙未激活” 的方式可能很弱。 (a) 你看,iptables -L 命令并不是真的用于文本处理。 (b) 有人可能添加了自定义链,但其中没有规则。这会让你的检查失败。

我真的不知道如何做得更好。可能更改防火墙规则是由管理员自己执行的任务,而不是由程序执行的任务。 :)

【讨论】:

    【解决方案2】:

    间距!

    错误:

    if [ "$A" == "$B"]; then
    

    对:

    if [ "$A" == "$B" ]; then
    

    [ 是一个命令;它需要在其单独的参数周围有空格(以及在其名称[ 周围),并且它的最后一个参数必须是]。有理由认为 = 而不是 == 更便携(但 == 在 Bash 中可以正常工作)。

    【讨论】:

    • 这是错误的.. 因为在所有状态下它都返回 false
    • 语法错误被正确识别和修复。如果您的字符串间距也有问题,那是一个单独的 bag'o'worms,对于不在您机器上的任何人来说都很难解决。因此,当您运行所显示的内容时,您会从test(又名[)命令中得到一个语法错误。由于间距问题,语法修复后测试也可能失败。
    【解决方案3】:

    由于iptables -L 末尾有空格,所以不匹配

    A=$(cat <<EOF
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    EOF
    )
    B="$(iptables -L)"
    
    diff -Z <(echo "$A") <(iptables -L) && echo "True" || echo "False"
    

    检查一下:

    顺便说一句,像这样调用meld 命令:meld &lt;(echo "$A") &lt;(iptables -L)(meld 是一个视觉差异工具)

    【讨论】:

    • 当它返回 false 时,它会显示一些与 diff 命令相关的 junc 数据。我怎样才能丢弃它们并打印false
    • @MLSC 使用这个:diff -q -Z &lt;(echo "$A") &lt;(iptables -L) &amp;&amp; echo "True" || echo "False",这里-q 选项的意思是quiet,即-q, --brief report only when files differ
    猜你喜欢
    • 2019-08-20
    • 2011-04-04
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 2021-03-08
    • 2014-07-15
    • 1970-01-01
    相关资源
    最近更新 更多