3

编者注:这个问题经过多次修改,改变了问题的性质,可能会使旧的评论和答案无效;它的原始标题是“无法将 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

静音模式效果很好。但是,如果我尝试详细模式,则会创建一个名为&or的文件&1(基于我的output变量)。此外,该文件是空的。这不是预期的结果:我希望输出留在终端上!

这是由于我重定向的顺序还是我的变量错误?编辑:脚本现在可以完全工作,通过将"&1"输出值替换为"/dev/tty".

4

2 回答 2

4

很可能正在打印错误输出。请注意,> /dev/null只有 stdout 会被重定向,而 stderr 不会。您可以2>&1在重定向标准输出之前使用将标准错误重定向到标准输出。就像是:

{
  # whatever commands...
} > $output 2>&1
于 2016-02-11T11:38:11.027 回答
0

tl;博士

  • 您不能将重定向存储到变量中的文件描述符&1在您的情况下)- 如果这样做,您将创建一个使用该名称的文件(在您的情况下按字面意思命名的文件)。&1

  • 不建议设置$output/dev/tty,因为您总是输出到终端,这会阻止在文件中捕获详细输出;例如,script -v > file不会工作。

  • 从注释中获取 gniourf_gniourf 的建议,并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

如果你使用一个变量,那没关系,因为变量内容总是被解释为一个文件名——这就是为什么你没有得到一个语法错误,而是以一个字面命名的输出文件结束&1

output='&1'
date >$output  #  !! Creates a *file* named '&1'.
date > $output #  !! Ditto.

为了解决您的问题,我建议从评论中获取gniourf_gniourf 的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
于 2016-02-22T15:01:29.523 回答