编写命令行应用程序时是否有何时使用错误的指南?令我惊讶的是,我在谷歌搜索时没有找到任何东西。
特别是,我现在关心的问题是是否使用stdout
或stderr
当用户使用非法参数调用程序时。然而,非常感谢更全面的答案,因为这肯定不是唯一需要明确规则来编写按照用户期望的方式运行的程序的情况。
答案1
stderr
是的,当使用错误的参数时一定会显示一条消息。如果这也导致应用程序退出,则以非零退出状态退出。
您应该使用标准错误流诊断信息或用于用户交互。诊断消息包括错误消息、警告和其他消息,这些消息不属于实用程序正确运行时的输出(“正确”意味着没有发生任何异常情况,例如未找到文件或其他任何情况)。
许多 shell(全部?)都会显示提示、用户键入的内容以及菜单等,stderr
因此重定向stdout
不会阻止您以有意义的方式与 shell 进行交互。
以下内容来自一篇博文关于这个主题:
这是 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
无论如何我们不会那样做, 我们要不要?)。
答案2
从POSIX 规范对于标准流:
程序启动时,应预定义三个流,无需显式打开:标准输入(用于读取常规输入)、标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。
换句话说,错误、调试信息和任何属于诊断类别的内容都会进入stderr
.
有关更多信息,请参阅相关问题:进度报告/日志信息属于 stderr 还是 stdout?