在 Bash 中按变量重定向 STDOUT



我想创建一个脚本,如果需要,它可以在详细和静默模式下运行。我的想法是创建一个包含"&> /dev/null"的变量,如果脚本静默运行,我只是清除它。静音模式工作正常,但如果我想将其作为最后一个"参数"传递给某些东西(请参阅我下面的示例(,它不起作用。

下面是一个示例:我想zip一些东西(我知道有一个-q的选择,这个问题更像是理论上的(,如果我写这个,它会按照我的预期工作:

$ zip bar.zip foo
  adding: foo (stored 0%)
$ zip bar.zip foo &> /dev/null
$

但是当我将&> /dev/null声明为变量时,我得到这个:

$ var="&> /dev/null"
$ zip bar.zip foo "$var"
zip warning: name not matched: &> /dev/null
updating: foo (stored 0%)

看到了其他有意重定向部分脚本的解决方案,但我很好奇我的想法是否可以工作,如果不能,为什么不呢?在我的脚本中使用这样的东西会更方便,因为我只需要重定向一些行或命令,但太多了,无法用if包围每个行或命令:

我正在尝试这样的事情来明确:

if verbose
verbose="&> /dev/null"
else
verbose=
command1 $1 $2
command2 $1
command3 $1 $2 $3 "$verbose"
command4

bash 在与重定向一起使用时,无论文件系统是否具有此类条目,都会将文件名 /dev/stdout 识别为标准输出。

# If an argument is given your script, use that value
# Otherwise, use /dev/stdout
out=${1:-/dev/stdout}
zip bar.zip foo > "$out"

您的问题是外壳执行的扩展顺序。 将命令传递给命令后,该变量将替换为您的标准输出重定向zip

在调用命令之前,您需要 shell 来扩展该变量zip。为此,您可以使用eval它首先通过扩展变量等。

eval zip bar.zip foo "$var"

但是,请厌倦使用 eval,因为未经检查的值可能会导致漏洞利用,并且通常不鼓励使用它。

您可以考虑设置自己的文件描述符,并将其设置为/dev/null、真实文件甚至 stdout。 然后,应该转到其中一个的每个命令将是:

zip bar.zip foo > 3

http://www.tldp.org/LDP/abs/html/io-redirection.html#FDREF

最新更新