bash中的条件重定向

dan*_*ann 21 bash conditional io-redirection

我有一个bash脚本,我希望在没有附加tty的情况下保持安静(比如来自cron).我现在正在寻找一种方法,在一行中有条件地将输出重定向到/ dev/null.这是我想到的一个例子,但我将有更多的命令在脚本中输出

#!/bin/bash
# conditional-redirect.sh
if tty -s; then 
  REDIRECT=
else 
  REDIRECT=">& /dev/null"
fi
echo "is this visible?" $REDIRECT
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用:

$ ./conditional-redirect.sh
is this visible?
$ echo "" | ./conditional-redirect.sh 
is this visible? >& /dev/null
Run Code Online (Sandbox Code Playgroud)

我不想做的是复制with-redirection或with-no-redirection变种中的所有命令:

if tty -s; then 
  echo "is this visible?"
else 
  echo "is this visible?" >& /dev/null
fi
Run Code Online (Sandbox Code Playgroud)

编辑:

如果解决方案能够为我提供一种以"安静"模式输出内容的方式,那将是很好的,例如,当某些事情确实出错时,我可能希望从cron获得通知.

pax*_*blo 26

对于bash,您可以使用以下行:

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

这将直接所有 stdout,并stderr/dev/null从该点.它使用非参数版本exec.

通常,类似的东西exec xyzzy会用新程序替换当前进程中的程序,但是你可以使用这个非参数版本来简单地修改重定向,同时保留当前程序.

因此,在您的具体情况下,您可以使用以下内容:

tty -s
if [[ $? -eq 1 ]] ; then
    exec &>/dev/null
fi
Run Code Online (Sandbox Code Playgroud)

如果您希望丢弃大部分输出但仍希望输出一些内容,则可以创建一个新的文件句柄来执行此操作.就像是:

tty -s
if [[ $? -eq 1 ]] ; then
  exec 3>&1 &>/dev/null
else 
  exec 3>&1
fi
echo Normal               # won't see this.
echo Failure >&3          # will see this.
Run Code Online (Sandbox Code Playgroud)

  • @theartofrain:您问_SO的另一个问题。_这样,每个人都看到了它,而不仅仅是我自己,因此您有更多的机会获得广泛的答案。FWIW,您可以存储当前的句柄:`exec 8>&1 9>&2&> / dev / null`,然后稍后执行`exec 1>&8 2>&9`进行恢复。 (3认同)

dan*_*ann 6

我找到了另一个解决方案,但是与paxdiablo的答案相比,我觉得它很笨拙:

if tty -s; then 
  REDIRECT=/dev/tty
else 
  REDIRECT=/dev/null
fi
echo "Normal output" &> $REDIRECT
Run Code Online (Sandbox Code Playgroud)

  • 这将起作用,但前提是不重定向输出。`/ dev / tty`总是指您的终端设备,因此,如果您使用`myscript> xyzzy.log`运行脚本,则发送到`/ dev / tty`的输出将不会在该日志文件中结束。尽管这取决于您要如何使用程序,但这可能并不重要。 (2认同)
  • @paxdiablo 你可以使用 `/dev/stdout` 而不是 `/dev/tty` 来解决这个问题 (2认同)

Cod*_*ope 5

您可以使用一个函数:

function the_code {
    echo "is this visible?"
    # as many code lines as you want
}

if tty -s; then # or other condition
  the_code
else 
  the_code >& /dev/null
fi
Run Code Online (Sandbox Code Playgroud)