1

(很抱歉最近没有照顾我的接受 - 我一有时间就会这样做;只是想问这个问题,现在它发生了)

考虑以下 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 之间是否存在性能差异(就流数据而言;也就是说,如果 fd 3 输出一个非常长的字节流,那么在 " " 情况下写入的每个字节是否会有指令惩罚3>/dev/null,而不是不寻址 fd 3)?

 

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

4

2 回答 2

4

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

没有什么。您未能捕获 的返回码write,它应该告诉您有一个错误,并且errno应该告诉您错误是什么

您似乎对持久性的概念也有疑问,“字节”仍然位于编译器从一开始就放置它们的字符串文字中。write将字节复制到流中。

于 2012-10-31T20:16:34.677 回答
0

詹斯是对的。如果您在两种情况下都在 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

这让我们想起了最佳实践 - 始终检查您的返回值。

于 2012-10-31T20:24:48.317 回答