如何抑制命令的输出,但在命令退出代码错误时显示它?
答案1
stderr
不幸的是,仅用于错误输出的假设并不总是正确的。相反,stderr
通常用于任何和所有交互的输出和诊断,即旨在供用户在交互式提示1中读取的输出。wget
是dd
众所周知的例子。
一些命令会提供一个标志(例如-quiet
或-silent
)来抑制非错误输出 - 阅读它们的手册页来查看是否存在。
另一个更常见的惯例是退出代码:程序退出时会返回退出代码。通常为2,退出代码0
表示成功,其他退出代码均表示错误。
使用bash
,您可以从变量中获取最后一个命令的退出代码$?
。在 中fish
,使用$status
变量。您可以管道传输stderr
到临时文件,并且仅在发生错误时打印它。例如 ( fish
):
command 2>/tmp/outputbuffer
if $status
cat /tmp/outputbuffer
rm /tmp/outputbuffer
如果您不链接命令,您还可以使用一些快捷方式:
if command 2>/tmp/outputbuffer
cat /tmp/outputbuffer
rm /tmp/outputbuffer
或者:
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
您还可以stdout
使用 管道传输到同一个缓冲区2>&1 >/tmp/outputbuffer
。
(注意:我实际上并不知道fish
,所以我根据文档中的内容调整了这个概念。语法可能略有错误。此外,您可以使用它mktemp
来生成一个唯一的临时文件 - 运行它并将文件名记录在变量中。)
如果你需要在一个你正在交互使用的 shell 的后台运行整个程序,那么你最好编写一个脚本来处理输出隐藏,并在后台运行该脚本标准技术(fish
)。哎呀,你可以在里面放入类似下面的函数~/.config/fish/config.fish
:
function run-silent
set temp (mktemp)
if $argv 2>&1 >$temp
cat $temp
rm $temp
end
调用run-silent somecommand &
(尾随&
导致它在后台运行)
请注意,这将吞掉原始退出代码,并在发生故障时转储和stdout
。您可以根据需要对其进行自定义。stderr
1甚至不能保证不会出现错误输出stdout
——有些程序会将所有输出转储到那里!
2不幸的是,情况并非总是如此 - 退出代码完全由程序控制,有些会以非零退出指示某些成功条件。再次检查手册。
答案2
Unix 实用程序将常规消息发送到stdout
,将错误消息发送到stderr
,因此,如果我们只想查看错误消息,则抑制它就足够了,stdout
因此只stderr
将输出发送到控制台。
执行此操作的方法是(在和中bash
)fish
附加>/dev/null
到命令。这会将 stdout 管道化为虚无,但 stderr(包含错误消息)仍会传递到控制台。
例如:
该命令echo 1 >/dev/null
不打印任何内容,因为正常stdout
输出被抑制,并且没有任何内容写入 stderr。
该命令man doesnotexist >/dev/null
打印一条错误消息,因为man
将其错误消息写入stderr
。
答案3
这将在后台运行命令并将错误写入日志文件,同时忽略正常输出
command > /dev/null 2> /tmp/example_error.log &