【问题标题】:How to compare grep result with a variable?如何将 grep 结果与变量进行比较?
【发布时间】:2014-08-29 08:01:46
【问题描述】:

我想将 grep 结果与变量进行比较。这是我的 bash 脚本

 check=$(grep "pam_wheel.so use_uid"  /etc/pam.d/su)
 result='#auth required pam_wheel.so use_uid'
        if [ "$check" =  "$result" ]; then
                echo "Access is not limited"
        else
                echo " limited access"       
        fi

我该怎么做?我尝试了很多组合,但我无法让它发挥作用。 提前致谢。

【问题讨论】:

  • grep "pam_wheel.so use_uid" /etc/pam.d/su 命令的确切输出是什么?
  • 正如@skwllsp 提到的,您的错误可能是在if 条件上,您分配(一个等号)而不是测试平等性(两个等号)
  • 你为什么不简单地用 grep 搜索整个结果字符串?
  • @skwllsp 不,单个等号是正确的语法,因为它与 sh 兼容,而 bash 可以同时识别两者。
  • @user000001,感谢您的评论

标签: bash shell


【解决方案1】:

/etc/pam.d/* 中的行被隔开以很好地排列。 greptest 对间距敏感(或者更确切地说,对您要比较的字符串中字节的任何语义不敏感)——如果字符串不完全相等,则比较将失败。

标准化间距的一种快速且相当优雅的方法是使用在空白处拆分的工具,例如 Awk。

if awk -v x=1 '$1 == "#auth" && $2 == "required" &&
               $3 == "pam_wheel.so" && $4 == "use_uid" {x=0}
            END{exit x}' /etc/pam.d/su
then
    echo "Access is not limited"
else
    echo "Access is limited"
fi

或外壳本身:

while read -r auth req so opts; do
    case $so:$opts in "pam_wheel.so:use_uid")
        test "$auth:req" == "#auth:required" &&
            echo "Access is not limited" ||
            echo "Access is limited" ;;
    esac
done </etc/pam.d/su

或两者的组合(这可能是最优雅的)。

或者,显式规范化所有空格:

case $(tr -s '\t ' ' ' </etc/pam.d/su | grep -m 1 "pam_wheel.so use_uid") in
    '#auth required pam_wheel.so use_uid')
        echo "Access is not limited";;
    *)  echo "Access is limited";;
esac

(还要注意这如何避免输出的讨厌的临时变量。)

【讨论】:

    【解决方案2】:

    您可以为此使用awk

    单线

    awk '/pam_wheel.so use_uid/ { if ($0 == "#auth required pam_wheel.so use_uid") {print "yes"; } else { print "no";} } ' /etc/pam.d/su
    

    Awk 脚本

    /pam_wheel.so use_uid/{ 
      if ($0 == "#auth required pam_wheel.so use_uid") {
        print "yes";
      } else { 
        print "no";
      }
    }
    

    说明

    • /pam_wheel.so use_uid/:将以下脚本应用于包含字符串 _pam_wheel.so use_uid_ 的行
    • $0:包含已处理的当前行(与您的模式匹配的行),我们再次测试您的值。
    • 经典if…else结构

    【讨论】:

    • 不需要对 awk 中的 if/else 如此明确。你可以做一些更惯用的事情,比如awk '/#auth required pam_wheel.so use_uid/ {print "yes"; f=1} END {if (!f) print "no"}' file
    • 我仍然得到输出为“否”。空白是否与比较有关?
    • 是的 awk 不要修剪线条,你可以在 else 中 print $0 看看它包含什么
    • 这仍然有点容易出错,因为正确位置的选项卡看起来就像一个空格。
    【解决方案3】:

    它不是你问题的答案,但也许它可以帮助你。

                result='#auth required pam_wheel.so use_uid'    
                grep "$result" /etc/pam.d/su && echo "Access is not limited" ||echo " limited access" 
    

    您的方法的另一件事是,如果您在 grep 中获得多个结果,您的结果变量将具有完整的两个结果,并且与您的 $result 变量不匹配。

                 check=$(grep -m 1"pam_wheel.so use_uid"  /etc/pam.d/su)
             result='#auth required pam_wheel.so use_uid'
                if [ "$check" =  "$result" ]; then
                    echo "Access is not limited"
                else
                    echo " limited access"       
                fi
    

    如果您的文件在文本周围有多余的空格,那么您将不得不修剪字符串以匹配。看看你的变量值是什么,你可以使用

                check=$(grep -m 1"pam_wheel.so use_uid"  /etc/pam.d/su)
                result='#auth required pam_wheel.so use_uid'
                echo "D""$check""D"
                echo "D""$result""D"
    

    这里的 D 只是任何其他字符,您可以查看两个变量是否具有相同数量的空格(这可能是比较失败的原因)。

    希望有帮助。快乐的脚本:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多