Upstart:通过管道传输多个命令的输出

Upstart:通过管道传输多个命令的输出

我尝试使用 upstart 脚本 (Ubuntu 12.04) 检测是否存在网络链接 (电缆插入/拔出)。下面是我的脚本的相关部分 (没有工作):

script
if  [ /sbin/ethtool eth0 | /bin/grep "Link detected: yes" > /dev/null ] ; then
    exec prog1
else
    exec prog2
fi

end script

(如果有链接则尝试启动 prog1,否则启动 prog2。)如何解决这个问题?

答案1

正确的方法是使用

if /sbin/ethtool eth0 | /bin/grep -q "Link detected: yes" ; then
    exec prog1
else
    exec prog2
fi

grep 的 -q 参数将丢弃 stdout,并且 if 语句检查它运行的命令的状态。[ /sbin/ethtool eth0 | /bin/grep -q "Link detected: yes" ]不是一个有效的命令,因为[实际上是一个接受像 grep 这样的参数的程序。所以[无法理解/sbin/ethtool eth0 | /bin/grep -q "Link detected: yes"并且失败。

答案2

您必须记住,Upstart 在 /bin/sh(即 Dash)中运行 shell 代码,而不是 /bin/bash。如果您将代码放入sh,它将不起作用:

$ if  [ /sbin/ethtool eth0 | /bin/grep "Link detected: yes" > /dev/null ]; then echo cheese; fi
sh: 9: [: missing ]
/bin/grep: ]: No such file or directory

所以这里面有一个语法问题。与其使用 bash 使用的隐式状态代码检查,我不如考虑像这样分解:

/sbin/ethtool eth0 | /bin/grep "Link detected: yes" > /dev/null
if  [ $? -eq 0 ]; then echo cheese; fi

以上内容对我有用sh


或者你可以强制 bash 行为将其包装在 bash 加载器中

script
/bin/bash <<EOT
    if  [ /sbin/ethtool eth0 | /bin/grep "Link detected: yes" > /dev/null ]; then echo cheese; fi
EOT
end script

相关内容