何时在命令行应用程序中使用标准错误流?


9

编写命令行应用程序时,何时有使用错误的准则?令我惊讶的是,在谷歌搜索时没有发现任何东西。

特别是,我现在关心的问题是是使用stdout还是stderr何时用户使用非法参数调用程序。但是,非常感谢您提供一个更全面的答案,因为这肯定不是唯一需要明确规则才能编写出符合用户期望的行为的程序的情况。


这些错误消息可以与常规输出混合在一起吗?例如,程序是数据过滤器吗?
thrig

它不是数据过滤器。它也不是交互式的。用户使用参数(在文件路径中)调用它,程序运行,更改这些文件,打印一些消息,理想情况下不打印任何错误消息并终止。
UTF-8

Answers:


15

是的,请stderr在使用错误的参数时显示一条消息。如果这也导致应用程序退出,请以非零退出状态退出。

您应该将标准错误流用于诊断消息或用户交互。诊断消息包括错误消息,警告和其他在实用程序正常运行时不属于输出的消息(“正确”表示没有异常事件发生,例如找不到文件或可能存在的任何错误)。

许多外壳程序(全部?)会显示提示,用户键入的内容以及菜单等,stderr因此重定向stdout不会阻止您以有意义的方式与外壳程序进行交互。

以下是关于该主题的博客文章

这是Unix管道的发明者Doug McIllroy的话,它解释了如何stderr实现。“ v6”是指1975年发布的原始Unix操作系统的特定版本。

所有程序都将诊断放在标准输出上。当将输出重定向到文件时,这总是会造成麻烦,但是当将输出发送到毫无怀疑的过程时,这将变得无法忍受。但是,由于不愿意违反标准输入标准输出模型的简单性,人们通过v6容忍了这种情况。此后不久,丹尼斯·里奇(Dennis Ritchie)通过引入标准误差文件切开了高迪安结。这还不够。使用管道,诊断可以来自同时运行的多个程序中的任何一个。诊断程序需要识别自己。
-Doug McIllroy,“研究UNIX的读者:1971-1986年程序员手册中的注释摘录”

“识别自己”意味着简单地说:“嘿!我在说话!这出了错:[...]”:

$ ls nothere
ls: nothere: No such file or directory

在这样做stderr是最好的,因为它可以通过,否则无论是阅读上阅读stdout(但我们不这样做,与ls无论如何,我们呢?)。


因此,当您在应用程序运行时向用户提问时,应该在stderr上打印问题吗?听起来不对。您有资料来源吗?这仅适用于除了问题和响应(用户可能希望通过管道传递到其他地方)以外的输出的应用程序吗?
UTF-8

@ UTF-8是否应将问题的文本视为程序输出的一部分?用户输入的内容如何?我不认为这应该是正确的(就像shell认为不应该那样)。但是也许取决于应用程序?
Kusalananda

1
感谢您的修改。同时,我检查了标准应用程序的行为,它们的行为类似于阅读您的答案后所期望的。
UTF-8

@ UTF-8,您可能会发现此问题与解答
terdon

6

根据POSIX规范的标准流:

在程序启动时,应预定义三个流,而不必显式打开它们:标准输入(用于读取常规输入),标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。

换句话说,错误,调试信息以及所有属于诊断类别的内容都会进入stderr

有关更多信息,请参见相关问题:进度报告/日志记录信息属于stderr还是stdout?

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.