我们知道,在UNIX shell中,&> outfilestdoutstderr重定向到outfile.但是shell如何实现这一点呢?我写了一个天真的测试:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main()
{
    int fd = open("tmpf", O_CREAT | O_TRUNC | O_WRONLY, 0644);
    // redirect stdout to file
    dup2(fd, 1);
    close(fd);
    // redirect stderr to stdout
    dup2(2, 1);
    close(2);
    // print stuff to file
    fprintf(stdout, "stdout string\n");
    fprintf(stderr, "stderr string\n");
}

它只是将stdout重定向到文件,然后将stderr重定向到stdout.但这不管用.上面的代码生成

$ ./a.out
stdout string
$ cat tmpf
$

如果我们交换stdout->filestderr->stdout的顺序,结果如下

$ ./a.out
$ cat tmpf
stdout string
$

推荐答案

不要关闭你的目的地FDs.唯一应该关闭的FD是tmpf上的手柄;stdout和stderr都需要开放,才能向它们进行写入.

另外,将stdout复制到stderr应该是dup2(1,2)——将stderr复制到stdout(就像原始代码那样)会丢弃tmpf上的句柄.

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main()
{
    int fd = open("tmpf", O_CREAT | O_TRUNC | O_WRONLY, 0644);
    // copy FD to stdout ("redirect stdout to fd")
    dup2(fd, 1);
    // fd was copied to stdout so we don't need the original
    close(fd);
    // copy stdout fd to stderr ("redirect stdout to stderr")
    dup2(1, 2);
    // print stuff to file
    fprintf(stdout, "stdout string\n");
    fprintf(stderr, "stderr string\n");
}

还可以在在线Sandbox 中看到https://replit.com/@CharlesDuffy2/KnowingWobblyFibonacci#main.c(可以使用"Show files"在输出中查看结果tmpf文件).

C++相关问答推荐

不同到达时间的轮询实现

为什么复合文字(C99)的返回会生成更多的汇编代码?

当多个线程在C中写入相同的文件描述符时,如何防止争用情况?

堆栈在作用域阻塞后会被释放吗?

为什么双重打印与C中的float具有不同的大小时具有相同的值?

为什么net/if.h在ifaddrs.h之前?

试图从CSV文件中获取双精度值,但在C++中始终为空

将uintptr_t添加到指针是否对称?

如何在STM8项目中导入STM8S/A标准外设库(ST VisualDeveloper)?

为什么中断函数会以这种方式影响数组?

防止C++中递归函数使用堆栈内存

在进程之间重定向输出和输入流的问题

Fscanf打印除退出C代码为1的程序外的所有内容

在链表中插入一个值

`void foo(int a[static 0]);` 有效吗?

C 预处理器中的标记分隔符列表

如何让 unlinkat(dir_fd, ".", AT_REMOVEDIR) 工作?

c 函数指针,另一种语法

牛顿分形优化

用C程序读取.txt文件并解析,如何处理空字段