如何使用Bash抑制命令的所有输出?

386
我有一个Bash脚本,运行一个带参数的程序。该程序会输出一些状态信息(正在做这个、正在做那个...)。该程序没有任何选项可以使其保持安静。我如何防止脚本显示任何东西?
我正在寻找类似于Windows的"echo off"的东西。
10个回答

653
以下代码将标准输出发送到空设备(位桶)。
以下发送标准输出到/dev/null:
```sh command > /dev/null ```
scriptname >/dev/null

如果你还希望错误消息也被发送到那个地方,请使用以下其中一个命令(第一个命令在某些shell中可能不起作用):

scriptname &>/dev/null
scriptname >/dev/null 2>&1
scriptname >/dev/null 2>/dev/null

如果你想记录这些信息,但不想看到它们,请将 /dev/null 替换为一个实际的文件,比如:

scriptname &>scriptname.out

为了完备性,在Windows的cmd.exe下(其中“nul”是“/dev/null”的等效物),它是:

scriptname >nul 2>nul

14
请注意,'&>' 是 Bash shell (也可能是 C shell) 特有的语法;而 Korn shell 和 Bourne shell 需要使用 2> /dev/null 或者 2>&1 (将 stderr 发送到与 stdout 相同的位置)。Korn shell 似乎将 '&>' 解释为“在后台运行到 & 符号之前的命令,然后对空命令执行 i/o 重定向”。 - Jonathan Leffler
5
注意,某些命令会直接写入终端设备而不是标准输出/错误输出。要测试,请在脚本中输入echo foo > $(tty)并运行./test.sh &> /dev/null - 输出仍将打印到终端上。当然,如果您编写的脚本未使用此类命令,则不会出现此问题。 - l0b0
2
@l0b0,有没有办法使脚本(或任何其他程序)的tty不同,以便所有输出都被重定向,而不管你的示例如何?我知道screen和script可以做到这一点,但两者都很棘手,并且在nix到nix之间有所不同。 - Brent
@yang 在 Cygwin 中存在 /dev/null,您不需要使用 nul - dimo414

57

类似于什么

script > /dev/null 2>&1

这将阻止标准输出和错误输出,将它们同时重定向到/dev/null


5
如果想省略一些打字,也可以只用&>就能实现同样的效果。 - andynormancx
1
尽管我将此添加到我的gs(GhostScript)命令中,它仍会打印出****警告:文件具有损坏的%%EOF标记或%%EOF之后的垃圾。有什么建议吗? - ZurabWeb
这不在Unix系统上运行该进程,我必须执行 2>/dev/null - alper

20

在某些情况下可能适用的另一种方法是将命令的结果分配给一个变量:

$ DUMMY=$( grep root /etc/passwd 2>&1 )
$ echo $?
0
$ DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
1

由于Bash和其他POSIX命令行解释器不将变量赋值视为命令,因此会尊重当前命令的返回码。

注意:使用typesetdeclare关键字进行赋值被视为一条命令,因此在这种情况下计算的返回码是赋值本身,而不是在子shell中执行的命令。

$ declare DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
0

18

尝试

: $(yourcommand)

: 是指“什么都不做”。

$() 只是你的命令。


4
非常有趣,但有一个限制:返回的状态码始终为 0(表示成功)。让我们举一个例子,使用命令 false,该命令始终返回 1(表示失败)。例如 ( echo foo | tee file ; false ) && echo bar 显示 foo。使用您的技巧来禁止输出:( : $(echo foo | tee file ; false) ) && echo bar。但是它显示 bar,这意味着返回的状态码是 0(而不是 false 的返回状态码)。请更新您的答案,提供此限制。谢谢 - oHo
3
@olibre,DUMMY=$(yourcommand) 呢?它没有你提到的限制。 :) - semente
3
命令“DUMMY=$( echo foo | tee file ; false ) && echo bar”不会显示任何内容。而命令“DUMMY=$( echo foo | tee file ; true ) && echo bar”则会显示“bar”。如果你提供了答案,让我知道一下,我会给你点赞的;-)祝好! - oHo
一种替代方案是使用 command | :,这样可能更容易输入。 - nadapez

8

如果你是在Unix环境下工作,请像andynormancx的帖子一样使用以下方法:

scriptname > /dev/null

如果您在Windows环境下工作,您可以使用以下方式:
scriptname > nul

1
在Windows shell中,您实际上可以做得比那更好。如果您使用“scriptname > nul”,则甚至不需要删除文件,因为“nul”是Windows中“/dev/null”的等效项。 - andynormancx
1
@andynormancx:这就是我讨厌Windows文件系统布局的原因。它“保留”像NUL、COM1、LPT1、CON等文件名,无论你在哪个目录下(即使你在一个可以使用这些文件名的文件系统中,比如网络共享中)。 - dreamlax
我认为自从DOS 5.x以来,我实际上就没有使用过NUL,当我看到这个答案时突然想起了它 ;) - andynormancx
如果您在Windows上使用cygwin或git bash时使用了> nul,现在卡在无法删除nul文件上,请尝试使用此答案,它的效果非常好。 - Daemon Painter

4
这是另一种选择。
scriptname |& :

考虑到它不需要在内存中缓冲命令的输出,我认为这可能是最好的选择。 - Tripp Kinetics
这是更聪明的解决方案。 - leandrovianna
1
为什么这个代码是“clever”(聪明的)?因为 : 会丢弃输入,所以它的作用类似于 /dev/null,但你却不必要地创建了一个无用的管道。 - tripleee

4

看看这个来自Linux文档项目的例子:

3.6 Sample: stderr and stdout 2 file

This will place every output of a program to a file. This is suitable sometimes for cron entries, if you want a command to pass in absolute silence.

     rm -f $(find / -name core) &> /dev/null 

话虽如此,您可以使用这个简单的重定向:

/path/to/command &>/dev/null

1
在你的脚本中,你可以在你知道会产生输出的行上添加以下内容:
some_code 2>>/dev/null

或者你也可以尝试

some_code >>/dev/null

2
从未看到过将其重定向到/dev/null..出于好奇..你为什么要这样做? - Florian Berndl
它是否抑制了所有输出? - Peter Mortensen
1
为什么使用双大于号(>>)? - Peter Mortensen
使用“>>”到null是不必要的,有些不正确,但在这种情况下是无害的。 - Bray

1

>&- 关闭文件描述符,甚至不会重定向到 /dev/null。

foo 2>&- >&-

也可以关闭标准输入 foo 2>&- >&- <&-


1
如果您正在后台运行命令并希望抑制其输出,则语法如下: (my_command > /dev/null &) 或者 (my_command > /dev/null 2>&1 &)

你能解释一下这两者之间的区别吗? - undefined
1
@osbm:区别在于2>&1部分,它是将标准错误输出重定向到标准输出。第一个命令只会抑制标准输出而不会抑制标准错误输出;而第二个命令会同时抑制两者。 - undefined
明白了,谢谢你。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接