何时在Shell脚本中使用重定向到stderr


15

我知道行为良好的实用程序,例如grep,会将“正常”消息输出到stdout,将错误消息输出到stderr。

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

当我自己编写shell脚本时,我经常发现很难决定应该在stderr上显示什么输出和哪些消息,或者是否应该打扰。

我想了解一种良好的做法:什么时候将某些消息重定向到stderr是合理的,什么时候不可行?

当然,“取决于情况”,但是您是否有一些见解可以帮助我做出这些决定?

为了使这个主观问题适合格式,我想鼓励回答“为什么”的答案,并以经验为基础,并在可能的情况下以事实为依据。


@rush完美地说明了这一点。我通常将进度报告打印到stderr以获取长脚本。
terdon

Answers:


12

当我自己编写shell脚本时,我经常发现很难决定应该在stderr上显示什么输出和哪些消息,或者是否应该打扰。

沉默是金。如果一切正常,则不输出任何内容。

我想了解一种良好的做法:什么时候将某些消息重定向到stderr是合理的,什么时候不可行?

将stderr与stdout分开的最简单方法是:想象所有脚本输出将通过管道重定向到另一个命令。在这种情况下,您应该将所有通知保留在stderr中,因为stdout中的此类意外信息可能会中断管道序列。

有时在这样的管道中:

command1 | while read line ; do command2 ; done | command3

您需要将某些内容传递command2给用户输出。没有临时文件的最简单方法是stderr。


感谢您提出“想象管道”的想法。有时我部署的脚本除了“通知”外什么也不做(echo一些变量,显示已完成的操作,显示进度)。我不愿将所有内容放到stderr上,因为这些日志消息是脚本将输出的所有消息。我不确定在这些情况下如何应用管道的想法。
2013年

1
@glts程序总是在被修改和改进。尽管您提到的脚本现在不输出任何数据,但它们可能稍后出现,或者您可以将它们用作其他脚本的起点。如果您遵循约定,那么以后您会收到更少的惊喜。OTOH,如果您只想将输出保存到文件中,则必须重定向stderr,因此这是与其他所有事物一样的权衡。
2013年

+1另一个表述:确保标准输出始终是机器可读的,或者至少包含一致格式的有用文本数据。
2013年

2

我涉及所述应用程序操作通常写入一切stderrstdout被保留用于数据。

想象一个像这样的应用程序cat。当您使用它读取输入并将其传递到另一个应用程序(通过管道)时,您不希望输出中出现状态消息。

可能对另一个应用程序或我的应用程序的后处理器感兴趣的stdout所有内容,仅与我的应用程序内部相关的所有内容都将涉及stderr


0

我个人的喜好是将错误消息和异常stderr发送给stdout。IMO,stderr有任何例外,因此是我的约定。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.