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

时间:2012-10-17 23:13:38

标签: bash shell variables redirect

我有几个BASH脚本使用命令和参数的变量来启动我经常使用的常见参数的程序。调用最终出现在这样:

$PROGRAM $ARG1 $ARG2 &

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

$PROGRAM $ARG1 $ARG2 $REDIRECTION &

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

3 个答案:

答案 0 :(得分:4)

一个选项是使用eval内置函数,它像Bash命令一样处理其参数,处理重定向运算符之类的事情。但是,eval风险很大,因为它会重新处理所有的参数,甚至是已经正确处理的参数,如果不这样做,这会导致奇怪或不安全的行为完美

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

exec >/dev/null 2>&1

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

[[ "$IS_VERBOSE" ]] || exec >/dev/null 2>&1

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

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

(
    [[ "$IS_VERBOSE" ]] || exec >/dev/null 2>&1
    "$PROGRAM" "$ARG1" "$ARG2" &
)

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

(顺便说一下,请注意我已将2>&1 > /dev/null更改为> /dev/null 2>&1:订单很重要。)

答案 1 :(得分:1)

不要尝试将shell语法编码为参数,只需将每个重定向运算符的默认目标放在参数中,并允许使用方法来覆盖默认值。

# A little bash-specific, but appropriate defaults should exist for the shell
# of your choice.
STDOUT=/dev/stdout
STDERR=/dev/stderr

if some-test; then
    STDOUT=some-other-file
fi

if some-other-test; then
    STDERR=different-file
fi

$PROGRAM $ARG1 $ARG2 > $STDOUT 2> $STDERR

答案 2 :(得分:0)

您可以构建您喜欢的任何命令行,然后使用eval执行它:

line="echo hello"
if ....
    line="$line > junk.out"
fi

eval $line

(我可能会选择你认为更容易阅读和理解的2行方法......)