当命令作为变量传递时,如何在命令替换中包含 stdout/stderr 重定向?

How to include stdout/stderr redirection with command subsitution when command passed as a variable?

我有以下脚本来检测我的网络在重启路由器后何时恢复:

#!/bin/bash
pingCommand="ping 192.168.1.1 -c 3 &>/dev/null"

while [[ ! $($pingCommand) ]]; do
   sleep 3s;
done

但是,当在终端中 运行 时,它会打印:

ping: unknown host &>/dev/null

我 运行 带有 -x 选项的脚本(启用调试)并发现

ping 192.168.1.1 -c 3 &>/dev/null

在子 shell 中被执行为

ping 192.168.1.1 -c 3 '&>/dev/null'

如何更改我的命令替换调用,以便 bash 不在输出重定向周围放置单引号?

Don't store commands in variables. Use functions. 他们处理重定向和管道时没有困扰变量的引用问题。

当您将所有输出重定向到 /dev/null 时,尝试捕获 ping 的输出也没有意义。如果你只是想知道它是否有效,请检查它的退出代码。

pingCommand() {
    ping 192.168.1.1 -c 3 &>/dev/null
}

while ! pingCommand; do
   sleep 3s;
done

使用eval:

#!/bin/bash
pingCommand="ping 192.168.1.1 -c 3 &>/dev/null"

# set -x # uncomment to see what's going on

while ! eval $pingCommand ; do
   sleep 3s;
done

而且您不需要 [[ ]](表达式求值)或 $()(输出捕获)。

当然,正如 John Kugelman 在另一个答案中所建议的那样,使用这些函数可以避免与 eval.

相关的所有潜在陷阱