如何使用 Bash 抑制命令的所有输出?
Posted
技术标签:
【中文标题】如何使用 Bash 抑制命令的所有输出?【英文标题】:How can I suppress all output from a command using Bash? 【发布时间】:2010-10-11 15:47:16 【问题描述】:我有一个运行带有参数的程序的 Bash 脚本。该程序输出一些状态(做这个,做那个......)。该程序没有任何选项可以保持安静。如何防止脚本显示任何内容?
我正在寻找类似 Windows 的 "echo off"。
【问题讨论】:
【参考方案1】:以下将标准输出发送到空设备(位桶)。
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
【讨论】:
请注意,'&>' 是 bash 所特有的(也可能是 C shell); Korn 和 Bourne shell 需要 2> /dev/null 或 2>&1(将 stderr 发送到与 stdout 相同的位置)。 Korn shell 似乎将 '&>' 解释为“在后台运行内容到 &,然后在空命令上执行 i/o 重定向”。 请注意,有些命令直接写入终端设备而不是标准输出/错误。要进行测试,请将echo foo > $(tty)
放入脚本并运行./test.sh &> /dev/null
- 输出仍会打印到终端。当然,如果您正在编写不使用此类命令的脚本,这不是问题。
@l0b0,有没有办法使脚本(或任何其他程序)的 tty 不同,以便无论您的示例如何都重定向所有输出?我知道屏幕和脚本可以做类似的事情,但两者都很挑剔,从 *nix 到 *nix 不等。
@yang /dev/null
存在于 Cygwin 中,您不需要使用 nul
。【参考方案2】:
类似
script > /dev/null 2>&1
这将防止标准输出和错误输出,将它们都重定向到/dev/null
。
【讨论】:
如果你想节省一些输入,也可以用 &> 实现;) 即使我将它添加到我的 gs (GhostScript) 命令中,它仍然会打印出 **** 警告:文件的 %%EOF 标记已损坏,或者 %%EOF 后出现垃圾。有什么建议吗? 这不会在unix系统上运行进程,我必须这样做2>/dev/null
【参考方案3】:
像andynormancx' post 一样,使用这个(如果您在 Unix 环境中工作):
scriptname > /dev/null
或者您可以使用它(如果您在 Windows 环境中工作):
scriptname > nul
【讨论】:
您实际上可以比在 Windows shell 中做得更好。如果改为使用“scriptname > nul”,那么您甚至没有要删除的文件,因为“nul”是 /dev/null 的 Windows 等价物。 @andynormancx:这就是我讨厌 Windows 文件系统布局的地方。它“保留”诸如 NUL、COM1、LPT1、CON 等文件名,无论您在哪个目录中(即使您在可以具有这些文件名的文件系统中,例如在网络共享中)。 我想我从 DOS 5.x 开始就没有真正使用过 NUL,当我看到这个答案时突然想起了 ;) 如果您在 Windows 上使用 cygwin 或 git bash 使用> nul
,现在您遇到无法删除的 nul
文件,请尝试 this answer,它就像一个魅力。【参考方案4】:
这是另一种选择
scriptname |& :
【讨论】:
我认为可能是最好的一个,因为它不需要在内存中缓冲命令的输出。【参考方案5】:试试
: $(yourcommand)
:
是“什么都不做”的缩写。
$()
只是你的命令。
【讨论】:
非常有趣但有一个限制:返回的状态码总是0
(成功)。让我们看一个使用命令false
的示例,它总是返回1
(失败)。例如( echo foo | tee file ; false ) && echo bar
显示foo
。使用您的技巧来抑制输出:( : $(echo foo | tee file ; false) ) && echo bar
。但它显示bar
,表示返回状态码是0
(这不是false
返回的状态码)。请更新您的答案,提供此限制。干杯
@olibre,DUMMY=$(yourcommand)
呢?它没有你提到的限制。 :)
@semente Perfect:命令DUMMY=$( echo foo | tee file ; false ) && echo bar
不显示任何内容。并且命令DUMMY=$( echo foo | tee file ; true ) && echo bar
显示bar
。让我知道您是否提供了支持它的答案;-) 干杯【参考方案6】:
在某些情况下可能适合的替代方法是将命令的结果分配给变量:
$ DUMMY=$( grep root /etc/passwd 2>&1 )
$ echo $?
0
$ DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
1
由于 Bash 和其他 POSIX 命令行解释器不将变量赋值视为命令,因此尊重当前命令的返回码。
注意: 带有typeset
或declare
关键字的赋值被视为一个命令,因此在case 的评估返回码是赋值本身而不是在子shell 中执行的命令:
$ declare DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
0
【讨论】:
【参考方案7】:看看这个来自 The Linux Documentation Project 的例子:
3.6 示例:stderr 和 stdout 2 文件
这会将程序的每个输出都放到一个文件中。如果您希望命令在绝对静默中传递,这有时适用于 cron 条目。
rm -f $(find / -name core) &> /dev/null
也就是说,你可以使用这个简单的重定向:
/path/to/command &>/dev/null
【讨论】:
【参考方案8】:在您的脚本中,您可以将以下内容添加到您知道将提供输出的行中:
some_code 2>>/dev/null
否则你也可以试试
some_code >>/dev/null
【讨论】:
从来没有看到 >> 到 /dev/null.. 出于好奇.. 你为什么要这样做? 是否抑制所有输出? 为什么是双 ">" (>>
)?
使用 >> 到 null 是不必要的,而且有些不正确,但在这种情况下,是无害的。以上是关于如何使用 Bash 抑制命令的所有输出?的主要内容,如果未能解决你的问题,请参考以下文章