【问题标题】:Use awk output as variable for string comparison使用 awk 输出作为字符串比较的变量
【发布时间】:2019-01-20 05:30:54
【问题描述】:

我在 macOS (High Sierra) 上过滤 ifconfig 的输出,以使用简单的 if 语句触发操作,尽管相应的字符串似乎匹配但并未触发该操作(使用 @987654322 进行测试时) @)。

脚本运行时,如果网络en1处于活动状态,则预期的操作是打印OK。

我试过了:

  • printf "%s" 在awk 命令中
  • 对"active" 使用双引号(简单)
  • 将active 保存在变量中以进行比较
  • 将en1_status=`...` 替换为en1_status=$(...)

没有成功。

#!/bin/bash
en1_status=`ifconfig en1 | grep "status: " | awk '{print $2}'`
if [ "$en1_status" = active ]; then
    echo OK
fi

而$en1_status 似乎与active 匹配:

echo $en1_status
active

【问题讨论】:

  • 请务必在您的帖子中提及预期输出是什么?
  • 关于行为,在en1 处于活动状态的情况下,脚本看起来确实设置了ALL_PROXY 变量。但是,您并没有解释您期望发生的事情。我推测问题是您希望在命令返回后设置 ALL_PROXY 变量;这不会发生,因为变量向下继承,并且不会传播回调用者。
  • 运行bash -x yourscript 来记录执行。 echo 不可信——你可以很容易地得到看起来相同但实际上不同的字符串。
  • 顺便说一句,grep | awk 毫无意义,因为awk 可以做任何事情grep 可以做更多; en1_status=$(ifconfig en1 | awk '/status: / { print $2 }') 会做同样的事情,而无需在管道中进行额外的处理。
  • 嗯。我想知道您是否将grep 配置为即使输出到 FIFO 也可以进行颜色突出显示?这可以解释为什么切换到 awk 可以解决问题(它应该只是性能调整,而不是修复)。

标签: macos shell awk


【解决方案1】:

这通常意味着您的变量中有不可打印的字符——例如语法高亮或 DOS 换行符。

发生这种情况的一种简单方法是,如果您将 grep 实例设置为始终插入颜色代码,就像使用 --color=always 而不是默认的(更安全的)--color=auto。

要跟踪这一点,请比较以下命令的输出:

printf '%s' "$en1_status" | xxd
printf '%s' inactive | xxd

您也可以通过让awk 进行搜索来模拟grep 的配置:

en1_status=$(ifconfig en1 | awk '/status: / { print $2 }')

【讨论】:

    【解决方案2】:

    您的解决方案适用于 MacOS,如果您在 if 比较的右侧加引号(我将 inactive 替换为本地测试,因为该接口对我来说在本地不活动):

    ~/> cat test.sh
    
    #!/bin/bash
    en1_status=`ifconfig en1 | grep "status: " | awk '{print $2}'`
    if [ "$en1_status" = "inactive" ]; then
        echo OK
    fi
    

    当我运行它时:

    ~/> ./test.sh 
    OK
    

    【讨论】:

    • 没有必要引用右侧(当它是一个没有语法相关字符的常量字符串并且您使用[ ]而不是[[ ]]时)。行为与未引用的行为 100% 相同。因此,虽然您在这里所说的一切都是错误的(我相信您脚本的行为方式与您所说的一样!),但这个答案可以说是具有误导性的,因为它提出了一个不会产生任何影响的变化,就好像它是一个修复。
    • (如果 OP 有 DOS 换行符,或者从有它们的源复制并粘贴,我不会感到惊讶 - 如果不是将 inactive 分配给他们正在分配的变量inactive$'\r' 因为在他们的代码中 en1_status=... 行的末尾有一个字面回车,这解释了他们的错误,并且解释了为什么除了他们之外没有人可以重现它)。
    • 我的没有,这里是bash-r的输出:++ ifconfig en1 ++ grep 'status: ' ++ awk '{print $2}' + en1_status='inactive' + '[' 'inactive' = inactive ']'
    • @Marc,很有趣——因为set -x 认为它需要引用它,所以有些东西是不可打印的,但它仍然没有明显呈现。 LC_ALL=C printf '%q\n' "$en1_status" 的输出是什么?或者,为了更加偏执/谨慎(以不依赖于您正在运行的 shell 版本/版本的方式),您可以比较 printf '%s' "$en1_status" | xxd 和 printf '%s' inactive | xxd
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 2019-03-02
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多