为什么 [ sudo docker ps | ... ] 在 bash 中语法无效?



所以我正在尝试学习awk。我想做一个sudo docker ps,如果第二行的第二列的第一个元素是x,则它打印ok

#!/bin/bash
if [ sudo docker ps | awk 'FNR == 2 {print $2}' = "portainer/agent" ]
then
     echo "Sucess"
else
     echo "Error"
fi

问题:

这是我们解析尴尬的方式吗?(docker ps | awk)?输出说找不到命令。

我想我在某处弄乱了一些狂欢基础知识...

我应该做

sudo docker ps
if [ awk 'FNR == " {print $2}' = "portainer" ]
then
    echo "sucess"
else
    echo "error"

没有解决docker ps输出的第2行(是稳定接口?)的智慧,但是您要寻找的语法是(可能有很多选择!):

#!/bin/bash
if sudo docker ps | awk 'FNR == 2 && $2 == "portainer/agent" {s=1} END {exit !s}'
then
     echo "Success"
else
     echo "Error" >&2
fi

要注意的几件事:不要打扰[命令。相反,只需评估尴尬的回报状态即可。awk返回!s,因为Shell中的成功由零状态表示;除非满足条件,否则变量s的值将为零,因此我们在返回外壳之前将其反转。请注意,"错误"写入stderr。错误消息需要转到正确的位置。

另一种选择(我真的建议您要解决,但是许多人以这种方式做事,所以知道语法是很好的)是用以下方式检查awk的输出。

if test "$(sudo docker ps | awk 'FNR == 2 && $2 == "portainer/agent" {print "ok"}
    ')" = ok; then ...

请注意,我正在使用test而不是[。它们是同一件事,除了test不需要其最终论点是],而且我认为,当读者不愿意认为[是语法的一部分,并且是某种操作员,我认为Shell脚本的混乱少得多。。但这完全是一种风格的选择。有些人会争辩说,您绝不应该使用[test,而是使用[[(这是语法的一部分)。ymmv

在这里,请注意引号。不需要引用原始字符串ok,因为它不受单词分割的约束,尽管许多样式指南(理所当然)建议引用它。我在这里毫无疑问地强调下一点。引用该过程替换的输出所需的是,因为如果awk不打印,您不想将空字符串作为参数传递给test。如果没有引号,则将第一个参数传递给test=,这将产生错误。通常,双引号的目的是防止单词分裂并定义空字符串。但是,这与您的问题并不重要,并且应该比这些评论更冗长。

最新更新