Bash:根据标志重定向到屏幕或/ dev / null

时间:2014-09-03 01:58:40

标签: bash dev-null

我正在尝试使用方法脚本在bash中传递 silent 标志,以便所有输出都会定向到/dev/null(如果存在)并显示在屏幕上如果不是。

我的剧本的MWE将是:

#!/bin/bash

# Check if silent flag is on.    
if [ $2 = "-s" ]; then
    echo "Silent mode."
    # Non-working line.
    out_var = "to screen"
else
    echo $1
    # Non-working line.
    out_var = "/dev/null"
fi

command1 > out_var

command2 > out_var

echo "End."

我用两个变量调用脚本,第一个是不相关的,第二个是$2)是实际的无声标志-s):

./myscript.sh first_variable -s

显然,out_var行不起作用,但它们会让我知道我想要的内容:将command1command2的输出指向屏幕或/dev/null取决于-s是否存在。

我怎么能这样做?

4 个答案:

答案 0 :(得分:4)

您可以使用裸exec命令重定向当前程序而无需启动新程序。

因此,可以使用以下内容处理-s标志:

if [[ "$1" == "-s" ]] ; then
    exec >/dev/null 2>&1
fi

以下完整脚本显示了如何执行此操作:

#!/bin/bash

echo XYZZY

if [[ "$1" == "-s" ]] ; then
    exec >/dev/null 2>&1
fi

echo PLUGH

如果您使用-s运行它,则会获得XYZZY但没有PLUGH输出(从技术上讲,您获取PLUGH输出但它被发送到/dev/null位桶。

如果你在没有 -s的情况下运行,你就会得到这两行。

前后echo语句显示exec的行为与描述相同,只是更改当前程序的重定向,而不是尝试重新执行它。


顺便说一句,我认为你的意思是“筛选"当前的标准输出",它可能是也可能不是实际的终端设备(例如,如果它已经被重定向到其他地方)。如果你想要实际的终端设备,它仍然可以完成(例如使用/dev/tty),但这是一个不寻常的要求。

答案 1 :(得分:1)

你的剧本有很多可能出错的地方;我不会尝试猜测,因为你没有发布任何实际输出或错误。

但是,有几件事情可以提供帮助:

  1. 您需要确定输出的实际位置。标准输出和标准错误是两个不同的东西,重定向一个不一定重定向另一个。

  2. 在Bash中,您可以将输出发送到 / dev / stdout / dev / stderr ,因此您可能需要尝试以下内容:

    # Send standard output to the tty/pty, or wherever stdout is currently going.
    cmd > /dev/stdout
    
    # Do the same thing, but with standard error instead.
    cmd > /dev/stderr
    
  3. 将标准错误重定向到标准输出,然后将标准输出发送到 / dev / null 。订单在这里很重要。

    cmd 2>&1 > /dev/null
    
  4. 您的脚本可能还有其他问题,但对于Bash shell redirections的问题,GNU Bash手册是规范的信息来源。希望它有所帮助!

答案 2 :(得分:0)

如果您不想重定向脚本中的所有输出,则可以使用eval。例如:

$ fd=1
$ eval "echo hi >$a" >/dev/null

$ fd=2
$ eval "echo hi >$a" >/dev/null
hi

确保使用双引号,以便在eval评估变量之前替换变量。

答案 3 :(得分:0)

在您的情况下,您只需将out_var = "to screen"更改为out_var = "/dev/tty"即可。并按照command1 > $out_var使用它(请参阅' $'您缺少)

我像这样实现了它

# Set debug flag as desired
DEBUG=1
# DEBUG=0

if [ "$DEBUG" -eq "1" ]; then
  OUT='/dev/tty'
else
  OUT='/dev/null'
fi

# actual script use commands like this
command > $OUT 2>&1

# or like this if you need
command 2> $OUT

当然您也可以从cli选项设置调试模式,请参阅How do I parse command line arguments in Bash?

你可以有多个像这样的调试或详细级别

# Set VERBOSE level as desired
# VERBOSE=0
VERBOSE=1
# VERBOSE=2

VERBOSE1='/dev/null'
VERBOSE2='/dev/null'

if [ "$VERBOSE" -gte 1 ]; then
  VERBOSE1='/dev/tty'
fi

if [ "$VERBOSE" -gte 2 ]; then
  VERBOSE2='/dev/tty'
fi

# actual script use commands like this
command > $VERBOSE1 2>&1

# or like this if you need
command 2> $VERBOSE2