编者注::这个问题经历了多次修改,改变了问题的性质,可能使较旧的评论和答案无效;它的原始标题是“无法将Bash输出重定向到/ dev / null”。
我正在尝试创建一个我想要实现静默模式的小Bash脚本。基本上我只是默认隐藏大部分输出,如果我用-v
运行它,显示所有输出。
所以在我的剧本开头我已经提到:
#!/bin/bash
declare output=''
if [ "$1" = -v ]; then
output="&1"
else
output="/dev/null"
fi
然后在我的脚本中我有:
{
# whatever commands...
} > $output 2>&1
静音模式效果很好。但是,如果我尝试详细模式,则会创建一个名为&
或&1
(基于我的output
变量)的文件。此外,该文件为空。这不是理想的结果:我希望输出保留在终端上!
这是由于我重定向的顺序还是我的变量是错误的?编辑:通过将"&1"
替换为"/dev/tty"
的输出值,脚本现在可以完全正常工作。
答案 0 :(得分:4)
很可能是错误输出正在打印。请注意,对于> /dev/null
,仅重定向stdout而不重定向stderr。在重定向stdout之前,可以使用2>&1
将stderr重定向到stdout。类似的东西:
{
# whatever commands...
} > $output 2>&1
答案 1 :(得分:0)
<强> TL;博士强>
您无法在变量中将重定向存储到文件描述符(在您的案例中为&1
) - 如果您这样做,您将创建取而代之的是一个文件(在你的情况下,一个名为&1
的文件)。
将$output
设置为/dev/tty
是不明智的,因为然后总是输出到终端,这会阻止捕获文件中的详细输出;例如,script -v > file
将无效。
从评论中获取gniourf_gniourf's建议,然后使用exec
:exec > /dev/null 2>&1
或使用特定于Bash的语法exec &>/dev/null
使脚本的其余部分静音
重定向到文件描述符只能起作用:
>
与目标之间没有空格。date > &1 # !! SYNTAX ERROR: syntax error near unexpected token `&'
date >&1 # OK - but works with a *literal* `&1` only
如果您使用变量,那无关紧要,因为变量内容总是被解释为 filename - 这就是您没有得到语法错误的原因,但最后输出的文件名为&1
。
output='&1'
date >$output # !! Creates a *file* named '&1'.
date > $output # !! Ditto.
要解决您的问题,我建议您从评论中提出gniourf_gniourf's建议:改为使用exec
:
#!/usr/bin/env bash
if [[ $1 == '-v' ]]; then
: # verbose mode: redirect nothing
else
# quiet mode: silence both stdout and stderr
exec &>/dev/null
fi
echo 'hello' # will only print with -v specified
echo 'hello' >&2 # ditto