如何将标准输出重定向到文件并恢复标准输出?

3

这是我的代码,但我无法让它正常工作。

int pfd = open("file", O_WRONLY, 0777);
int saved = dup(1);
close(1);
dup(pfd);
close(pfd);
printf("This goes into file\n");

// restore it back
dup2(saved, 1);
close(saved);
printf("this goes to stdout");

我对我的代码进行了一些修改。


dup(pfd); 不会使 stdout 写入文件。 - tkausl
你考虑过多次使用 dup2 吗? - Basile Starynkevitch
抱歉,我忘记在 dup(pfd) 之前添加 close(1) - posixKing
似乎是一个重复的问题,与此问题相同:这里 - bnaecker
但是我在第一行就打开了文件。那个链接中的解决方案在复制后才打开它。我该如何让我的代码工作? - posixKing
@posixKing 在复制了 stdin 之后打开了 文件。此时这两个文件是不相关的。这些操作的顺序会有什么影响呢? - bnaecker
1个回答

3
你需要检查函数调用的返回值。对于大多数函数,你都应该检查错误情况。这样做可能会揭示一个问题:如果你想让 open() 在文件不存在时创建请求的文件,则需要添加 O_CREAT 标志。
但这不是你在这里遇到的主要问题 —— 你正在处理缓冲问题。第一个 printf() 的输出被缓存在内存中,因此即使文件描述符1在调用 printf() 时指向你的文件,你写入的数据也不会立即刷新到目标文件。然后你恢复了原始的 stdout 文件句柄,所以当数据实际刷新时,它们会发往(恢复的)原始 stdout。在切换回 stdout 之前,使用 fflush() 解决这个问题:
int pfd = open("file", O_WRONLY | O_CREAT, 0777);
int saved = dup(1);

close(1);
dup(pfd);
close(pfd);
printf("This goes into file\n");
fflush(stdout);  // <-- THIS

// restore it back
dup2(saved, 1);
close(saved);
printf("this goes to stdout");

请注意,dup2() 在将文件描述符复制到 特定的 文件描述符编号上时更加干净和安全。在恢复时应该这样做,但对于初始重定向也应该这样做。

我的锅,这是我的错误。我会撤回评论。感谢您的答案。fflush就能搞定。 - posixKing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接