我对这三个文件的用途感到相当困惑。如果我的理解是正确的,stdin是程序写入它的请求以在进程中运行任务的文件,stdout是内核写入它的输出和它访问的请求进程的信息的文件,stderr是所有异常都输入的文件。在打开这些文件来检查这些是否真的发生了,我发现似乎没有什么建议!

我想知道的是这些文件的确切目的是什么,绝对愚蠢的答案与很少的技术术语!


当前回答

我认为人们说stderr应该只用于错误消息是一种误导。

它还应该用于为运行命令的用户而不是数据的任何潜在下游消费者提供的信息性消息(例如,如果您运行一个连接多个命令的shell管道,您不希望像“获取42424的item 30”这样的信息性消息出现在stdout上,因为它们会混淆消费者,但您可能仍然希望用户看到它们。

看看下面的历史逻辑:

"All programs placed diagnostics on the standard output. This had always caused trouble when the output was redirected into a file, but became intolerable when the output was sent to an unsuspecting process. Nevertheless, unwilling to violate the simplicity of the standard-input-standard-output model, people tolerated this state of affairs through v6. Shortly thereafter Dennis Ritchie cut the Gordian knot by introducing the standard error file. That was not quite enough. With pipelines diagnostics could come from any of several programs running simultaneously. Diagnostics needed to identify themselves."

其他回答

我认为人们说stderr应该只用于错误消息是一种误导。

它还应该用于为运行命令的用户而不是数据的任何潜在下游消费者提供的信息性消息(例如,如果您运行一个连接多个命令的shell管道,您不希望像“获取42424的item 30”这样的信息性消息出现在stdout上,因为它们会混淆消费者,但您可能仍然希望用户看到它们。

看看下面的历史逻辑:

"All programs placed diagnostics on the standard output. This had always caused trouble when the output was redirected into a file, but became intolerable when the output was sent to an unsuspecting process. Nevertheless, unwilling to violate the simplicity of the standard-input-standard-output model, people tolerated this state of affairs through v6. Shortly thereafter Dennis Ritchie cut the Gordian knot by introducing the standard error file. That was not quite enough. With pipelines diagnostics could come from any of several programs running simultaneously. Diagnostics needed to identify themselves."

It would be more correct to say that stdin, stdout, and stderr are "I/O streams" rather than files. As you've noticed, these entities do not live in the filesystem. But the Unix philosophy, as far as I/O is concerned, is "everything is a file". In practice, that really means that you can use the same library functions and interfaces (printf, scanf, read, write, select, etc.) without worrying about whether the I/O stream is connected to a keyboard, a disk file, a socket, a pipe, or some other I/O abstraction.

大多数程序都需要读取输入,写入输出,并记录错误,所以stdin, stdout, 和stderr是为您预定义的,以方便编程。这只是 一种约定,操作系统不强制执行。

stdin

通过控制台读取输入(例如键盘输入)。 在C语言中使用scanf

scanf(<formatstring>,<pointer to storage> ...);

stdout

产生输出到控制台。 在C中与printf一起使用

printf(<string>, <values to print> ...);

stderr

向控制台输出“错误”。 在C中与fprintf一起使用

fprintf(stderr, <string>, <values to print> ...);

重定向

stdin的源可以被重定向。例如,它不是来自键盘输入,而是来自文件(echo < file.txt)或另一个程序(ps | grep <userid>)。

stdout、stderr的目的地也可以重定向。例如,stdout可以重定向到一个文件:ls。> ls-output.txt,在这种情况下输出被写入文件ls-output.txt。Stderr可以用2>重定向。

stderr将不做IO缓存缓冲,所以如果我们的应用程序需要打印关键消息信息(一些错误,异常)到控制台或文件使用它作为使用标准输出打印一般日志信息,因为它使用IO缓存缓冲有一个机会,在写入我们的消息到文件应用程序可能会关闭,留下复杂的调试

作为上述答案的补充,以下是关于重定向的总结:

编辑:这张图并不完全正确。

第一个例子根本没有使用stdin,它将“hello”作为参数传递给echo命令。

图表还显示,2>&1与&>具有相同的效果

ls Documents ABC > dirlist 2>&1
#does not give the same output as 
ls Documents ABC > dirlist &>

这是因为&>需要重定向到一个文件,而2>&1只是将stderr发送到stdout