在Bash中通过变量重定向STDOUT

在Bash中通过变量重定向STDOUT,bash,stdout,io-redirection,Bash,Stdout,Io Redirection,我想创建一个脚本,如果愿意,它可以在详细模式和静默模式下运行。我的想法是创建一个包含“&>/dev/null”的变量,如果脚本以静默方式运行,我只需清除它。静默模式工作得很好,但如果我想将其作为最后一个“参数”传递给某个对象(请参见下面的示例),它就不起作用 以下是一个例子: 我想zip一些东西(我知道有一个-q选项,这个问题更像是道德问题),如果我写这篇文章,它会按照我的意图工作: $ zip bar.zip foo adding: foo (stored 0%) $ zip bar.zi

我想创建一个脚本,如果愿意,它可以在详细模式和静默模式下运行。我的想法是创建一个包含
“&>/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

您的问题是shell执行的扩展顺序。将命令传递到命令
zip

您需要shell在调用
zip
命令之前展开该变量。要做到这一点,您可以使用
eval
,它首先通过扩展变量等

eval zip bar.zip foo“$var”

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

<>您可以考虑设置自己的文件描述符,并将其设置为//DEV/NULL、实际文件,甚至STDUT。然后,每个应该发送到其中一个的命令将是:

zip bar.zip foo>3


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"

使用eval:
eval zip bar.zip foo“$var”
。或者使用if语句:
if条件;然后指挥;else命令>&/dev/null;fi
正如上面和下面提到的,如果
s和
eval
不被鼓励,我不想用
来包围一切。请尽量避免链接ABS——这是bash的W3Schools,充满了糟糕的实践示例和过时的信息,但却有着无法解释的Google果汁。BashHackers的wiki有两个关于重定向的页面——还有——BashGuide()和官方手册()中也有详细的介绍。