我对这三个文件的用途感到相当困惑。如果我的理解是正确的,stdin是程序写入它的请求以在进程中运行任务的文件,stdout是内核写入它的输出和它访问的请求进程的信息的文件,stderr是所有异常都输入的文件。在打开这些文件来检查这些是否真的发生了,我发现似乎没有什么建议!
我想知道的是这些文件的确切目的是什么,绝对愚蠢的答案与很少的技术术语!
我对这三个文件的用途感到相当困惑。如果我的理解是正确的,stdin是程序写入它的请求以在进程中运行任务的文件,stdout是内核写入它的输出和它访问的请求进程的信息的文件,stderr是所有异常都输入的文件。在打开这些文件来检查这些是否真的发生了,我发现似乎没有什么建议!
我想知道的是这些文件的确切目的是什么,绝对愚蠢的答案与很少的技术术语!
当前回答
使用ps -aux显示当前进程,所有这些进程都列在/proc/ as /proc/(pid)/中,通过调用cat /proc/(pid)/fd/0,它会打印在该进程的标准输出中找到的任何东西。因此,或许,
/proc/(pid)/fd/0 -标准输出文件 /proc/(pid)/fd/1 -标准输入文件 /proc/(pid)/fd/2 -标准错误文件
例如
但只有在/bin/bash中才能很好地工作,其他进程通常在0中没有任何内容,但在2中有许多错误
其他回答
作为上述答案的补充,以下是关于重定向的总结:
编辑:这张图并不完全正确。
第一个例子根本没有使用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
有关这些文件的权威信息,请查看手册页,在您的终端上运行该命令。
$ man stdout
但简单来说,每个文件都是用于:
输出流的Stdout
流输入的Stdin
打印错误或日志消息的标准错误。
每个unix程序都有这些流中的每一个。
标准输入——这是进程读取的文件句柄,以便从您获取信息。
标准输出—您的进程将常规输出写入此文件句柄。
标准错误-进程将诊断输出写入此文件句柄。
这是我能做到的最愚蠢的了:-)
当然,这主要是惯例。如果您愿意,没有什么可以阻止您将诊断信息写入标准输出。您甚至可以完全关闭三个文件句柄,并打开您自己的文件进行I/O。
当您的进程启动时,它应该已经打开了这些句柄,并且可以读取和/或写入它们。
默认情况下,它们可能连接到您的终端设备(例如,/dev/tty),但是shell将允许您在进程启动之前在这些句柄和特定的文件和/或设备(甚至是到其他进程的管道)之间建立连接(可能的一些操作相当聪明)。
一个例子是:
my_prog <inputfile 2>errorfile | grep XYZ
将:
为my_prog创建一个进程。 打开inputfile作为标准输入(文件句柄0)。 打开errorfile作为标准错误(文件句柄2)。 为grep创建另一个进程。 将my_prog的标准输出附加到grep的标准输入。
回复你的评论:
当我在/dev文件夹中打开这些文件时,为什么我从来没有看到进程运行的输出?
因为它们不是普通的文件。虽然UNIX将所有内容都作为文件系统中的某个文件,但在最低级别上并不是这样。/dev层次结构中的大多数文件不是字符设备就是块设备,实际上是一个设备驱动程序。它们没有尺寸,但有主设备号和副设备号。
当您打开它们时,您连接到的是设备驱动程序,而不是物理文件,而且设备驱动程序足够智能,知道应该分别处理不同的进程。
Linux /proc文件系统也是如此。这些不是真正的文件,只是严格控制的通往内核信息的网关。
下面是一篇关于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
具有讽刺意味的是,我在堆栈溢出和上面的文章中发现了这个问题,因为我正在搜索关于异常/非标准流的信息。所以我的探索还在继续。
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是为您预定义的,以方便编程。这只是 一种约定,操作系统不强制执行。