是否有可能linux文件描述符0 1 2不适用于stdin,stdout和stderr?

All*_*nHu 9 sockets linux kernel

程序开始时,默认情况下是否需要stdin,stdout和stderr的文件描述符0,1和2?API调用(例如open(...),socket(...))是否会返回0,1和2,因为这些值已经被采用了?是否存在open(...)或socket(...)返回0,1或2的情况.0,1和2与stdin,stdout和stderr无关.

Bas*_*tch 14

文件描述符级别,stdin被定义为文件描述符0,stdout被定义为文件描述符1 ; 和stderr被定义为文件描述符2.看到这个.

即使您的程序 - 或shell-更改(例如,使用dup2(2)重定向)什么是文件描述符0,它始终保持stdin(因为根据定义STDIN_FILENO为0).

因此,stdin当然可以是管道或套接字或文件(​​不是终端).如果它是tty,你可以使用isatty(3)进行测试,和/或使用fstat(2)来获取状态信息.

如果该文件描述符是空闲的(例如因为它之前已经接近(2) -d ),则像open(2)pipe(2)socket(2)这样的系统调用可以给出例如STDIN_FILENO(即0 ).但是当发生这种情况时,它仍然是stdin的定义.

当然,在stdio(3)中,FILEstdin有点复杂.你的程序可以fclose(3),freopen(3),fdopen(3) ......

当神奇地从第一个进程开始时,内核可能会将stdin,stdoutstderr文件描述符设置到控制台/sbin/init.

  • 很好的答案,但如果它承认所使用的定义的僵化(以及与提出此类问题的人可能试图表达的内容可能存在偏差),可能会更好。当一个进程将另一个 FD 重定向到 FD 0 时,是的,*在该进程内*(并且由子进程继承)它们重定向到 0 的任何内容现在都是“stdin”。但它绝对不再是以前的“stdin”,因此在另一个同样有效的单词与概念的绑定中,0 不再是“stdin” - 有时“是 stdin 吗?”的含义。更相关/有用。尽管如此,总体还是+1。 (2认同)

swa*_*ina 7

尽管已经存在一些答案,但我发现它们的信息不足以解释完整的故事。

由于我继续进行了更多研究,因此我正在添加我的发现。

每当进程启动时,正在运行的进程的条目就会添加到/proc/<pid>目录中。这是保存与流程相关的所有数据的地方。此外,在进程启动时,内核会向进程分配 3 个文件描述符,用于与 3 个数据流(称为stdinstdout和 )进行通信stderr
Linux 内核使用一种算法来始终创建具有尽可能低的整数值的 FD,以便这些数据流映射到数字012

因为这些只是对流的引用,所以我们可以关闭流。close(<fd>)在我们的例子中,我们可以轻松地调用close(1)来关闭文件描述符。

在这样做时ls -l /proc/<pid>/fd/,我们只看到那里列出了 2 个 FD02
如果我们现在进行调用,open()内核将创建一个新的 FD 来映射此新文件引用,并且由于内核使用最低整数优先算法,因此它将获取整数值1

所以现在,创建的新 FD 指向我们打开的文件(使用open()系统调用)。
现在发生的任何数据传输都不是通过之前链接的默认数据流,而是通过我们打开的新文件。

所以是的,我们可以将 FD 或 映射0到任何文件,但不是必需1的,或者2stdinstdoutstderr