所以我正在尝试学习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
是=
,这将产生错误。通常,双引号的目的是防止单词分裂并定义空字符串。但是,这与您的问题并不重要,并且应该比这些评论更冗长。