如何将重定向符号分配给变量以组装命令行

use*_*938 4 variables bash shell redirect

我有几个 BASH 脚本,它们使用命令和参数的变量来启动我常用的程序和常用参数。调用出现在最后,如下所示:

$PROGRAM $ARG1 $ARG2 &
Run Code Online (Sandbox Code Playgroud)

/dev/null现在我想默认将输出重定向到 stderr 和 stdout 。我希望能够通过切换到脚本(-v=详细)来禁用它。但是,如果我尝试分配"2>&1 > /dev/null"给一个 var,例如REDIRECTION(如果指定了 verbose,则清除它)并尝试像这样调用:

$PROGRAM $ARG1 $ARG2 $REDIRECTION &
Run Code Online (Sandbox Code Playgroud)

重定向指令作为参数传递给程序。有没有办法做到这一点?或者我是否必须使用我的解决方案,即有 2 个独立的调用行,一个有重定向指令,一个没有重定向指令,具体取决于“详细程度”?

rua*_*akh 5

一种选择是使用eval内置函数,它像 Bash 命令一样处理其参数,处理重定向运算符之类的事情。然而,eval这是相当危险的,因为它会重新处理它的所有参数,即使是那些已经正确处理的参数,如果做得不完美,这可能会导致奇怪或不安全的行为。

由于命令的两个版本之间唯一有问题的区别是是否存在重定向,因此更好的选择是使用exec内置命令。这个命令:

exec >/dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)

将 shell 脚本其余部分的 STDOUT 和 STDERR 重定向到/dev/null. 这个命令:

[[ "$IS_VERBOSE" ]] || exec >/dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)

exec >/dev/null 2>&1 除非 $IS_VERBOSE非空,否则它将运行,在这种情况下它什么也不做。(您可以替换[[ "$IS_VERBOSE" ]]为已用于检测详细程度的任何类型的条件表达式。)

所以,你想要的是这样的:

(
    [[ "$IS_VERBOSE" ]] || exec >/dev/null 2>&1
    "$PROGRAM" "$ARG1" "$ARG2" &
)
Run Code Online (Sandbox Code Playgroud)

括号( ... )用于设置一个子 shell,因此该exec命令(如果运行)仅影响到).

(顺便说一句,请注意我将您的更改2>&1 > /dev/null> /dev/null 2>&1:顺序很重要。)