Linux C:未使用的文件描述符会发生什么?

时间:2012-10-31 20:10:55

标签: c linux file-descriptor

(最近没有照顾我的接受道歉 - 一旦我有时间就会这样做;只是想现在就问这个问题)

考虑以下C程序:

int main(void) {
  write(3, "aaaaaa\n", 7);
  write(2, "bbbbbb\n", 7);
  write(1, "cccccc\n", 7);
  return 0;
}

我从bash shell构建并运行它,如下所示:

$ gcc -o wtest wtest.c
$ ./wtest 3>/dev/stdout
aaaaaa
bbbbbb
cccccc

我看到它的方式,在这种情况下,由于fd 3的shell重定向到stdout,该文件描述符现在被“使用”(不确定“打开”,因为没有打开文件,至少在C代码中) - 所以我们得到cccccc字符串输出到终端,如预期的那样。

如果我不使用重定向,则输出为:

$ ./wtest 
aaaaaa
bbbbbb

现在fd 3没有被重定向 - 所以cccccc字符串不再按预期输出。

我的问题是 - 那些cccccc个字节发生了什么变化?他们是否以同样的意义消失了,好像我将fd 3重定向到/dev/null? (如:

$ ./wtest 3>/dev/null

此外,假设在特定情况下我想“隐藏”fd 3输出:重定向“3>/dev/null”与不解决shell中的fd 3之间会有性能差异吗? all(就流数据而言;也就是说,如果fd 3输出一个非常长的字节流,那么在“3>/dev/null”情况下写入的每个字节是否会有一个指令惩罚,而不是寻址fd 3)?

非常感谢任何答案,
干杯!

2 个答案:

答案 0 :(得分:4)

  

我的问题是 - 那些cccccc字节发生了什么?

什么。您未能捕获write的返回代码,它应该告诉您存在错误,errno应该告诉您错误是什么

你似乎也有一个可疑的概念,即持久性,“字节”仍然位于编译器从头开始的字符串文字中。 write将字节复制到流中。

答案 1 :(得分:0)

Jens是对的。如果你在两种情况下使用strace运行你的程序,你会看到当你重定向时,写入工作 - 因为shell在你的可执行文件分叉之前代表你调用了pipe()。

当你看到没有重定向的strace时:

write(3, "aaaaaa\n", 7)                 = -1 EBADF (Bad file descriptor)
write(2, "bbbbbb\n", 7bbbbbb)                 = 7
write(1, "cccccc\n", 7cccccc)                 = 7

这提醒我们最佳做法 - 始终检查您的回报值。