我对这三个文件的用途感到相当困惑。如果我的理解是正确的,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."

其他回答

下面是一篇关于stdin, stdout和stderr的长篇文章:

Linux中的stdin、stdout和stderr是什么?

总结:

Streams Are Handled Like Files Streams in Linux—like almost everything else—are treated as though they were files. You can read text from a file, and you can write text into a file. Both of these actions involve a stream of data. So the concept of handling a stream of data as a file isn’t that much of a stretch. Each file associated with a process is allocated a unique number to identify it. This is known as the file descriptor. Whenever an action is required to be performed on a file, the file descriptor is used to identify the file. These values are always used for stdin, stdout, and stderr: 0: stdin 1: stdout 2: 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应该只用于错误消息是一种误导。

它还应该用于为运行命令的用户而不是数据的任何潜在下游消费者提供的信息性消息(例如,如果您运行一个连接多个命令的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."

A file with associated buffering is called a stream and is declared to be a pointer to a defined type FILE. The fopen() function creates certain descriptive data for a stream and returns a pointer to designate the stream in all further transactions. Normally there are three open streams with constant pointers declared in the header and associated with the standard open files. At program startup three streams are predefined and need not be opened explicitly: standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). When opened the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device

https://www.mkssoftware.com/docs/man5/stdio.5.asp

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

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

第一个例子根本没有使用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