bash 中的条件重定向

问题描述 投票:0回答:5

我有一个 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

不幸的是,这不起作用:

$ ./conditional-redirect.sh
is this visible?
$ echo "" | ./conditional-redirect.sh 
is this visible? >& /dev/null

我不想做的是在带重定向或不带重定向变体中复制所有命令:

if tty -s; then 
  echo "is this visible?"
else 
  echo "is this visible?" >& /dev/null
fi

编辑:

如果该解决方案能够为我提供一种以“安静”模式输出某些内容的方法,例如当确实出现问题时,我可能想从 cron 获得通知。

bash conditional-statements io-redirection
5个回答
33
投票

对于

bash
,您可以使用以下行:

exec &>/dev/null

这将从该点开始将 all

stdout
stderr
定向到
/dev/null
。它使用无参数版本的
exec

通常,像

exec xyzzy
这样的东西会用新程序替换当前进程中的程序,但您可以使用这个无参数版本来简单地修改重定向,同时保留当前程序。

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

tty -s
if [[ $? -eq 1 ]] ; then
    exec &>/dev/null
fi

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

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.

13
投票

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

if tty -s; then 
  REDIRECT=/dev/stdout
else 
  REDIRECT=/dev/null
fi
echo "Normal output" &> $REDIRECT

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

1
投票

这对我来说效果很好。如果

DUMP_FILE
为空,则转到标准输出,否则转到文件。它在不使用显式重定向的情况下完成这项工作,而仅使用管道和现有应用程序。

function stdout_or_file
{
    local DUMP_FILE=${1:-}

    if [ -z "${DUMP_FILE}" ]; then
        cat
    else
        sed -n "w ${DUMP_FILE}"
    fi
}

function foo()
{
    local MSG=$1
    echo "info: ${MSG}"
}

foo "bar" | stdout_or_file ${DUMP_FILE}

当然,你也可以把它挤成一行

foo "bar" | if [ -z "${DUMP_FILE}" ]; then cat; else sed -n "w ${DUMP_FILE}"; fi

除了

sed -n "w ${DUMP_FILE}"
之外,另一个具有相同功能的命令是
dd status=none of=${DUMP_FILE}


0
投票

最简单的解决方案是使用 eval (一个 shell 内置函数),因为它将作用于扩展变量中的重定向...并且还作用于命令行中的其他任何内容,因此根据需要添加额外的引号(注意额外的单引号)由于“?”,在下面的 echo 字符串周围添加了引号,否则会导致尝试扩展 shell 文件名)。

#!/bin/bash # conditional-redirect.sh if tty -s; then REDIRECT= else REDIRECT=">& /dev/null" fi eval echo '"is this visible?"' $REDIRECT
    
© www.soinside.com 2019 - 2024. All rights reserved.