我已经找了很长时间,找不到我问题的答案。
我试图用C语言重新生成一个shell,并进行完全重定向。为此,我想在执行命令之前打开文件。
例如,在ls > file1 > file2中,我使用dup2(file1_fd, 1)和dup2(file2_fd, 1)然后执行ls来填充文件,但标准输出似乎只能打开一次,因此只能填充file2,因为它是最后一个要复制的输出。
是否有方法将标准输出重定向到多个文件?
我有什么遗漏吗?谢谢!

最佳答案

您所要的是命令存在的确切原因(您可以查看它的源代码here)。
不能多次使用tee复制文件描述符。正如您已经看到的,最后一个将覆盖以前的任何复制。因此,不能直接使用dup2()将程序输出重定向到多个文件。
为此,您确实需要多个描述符,因此必须打开两个文件,使用dup2()启动命令,然后从管道读取并写入两个文件。
下面是一个非常简单的例子,说明了如何做到这一点:

#include <stdio.h>
#include <stdlib.h>

#define N 4096

int main(int argc, const char *argv[]) {
    FILE *fp1, *fp2, *pipe;

    fp1 = fopen("out1.txt", "w");
    if (fp1 == NULL) {
        perror("fopen out1 failed");
        return 1;
    }

    fp2 = fopen("out2.txt", "w");
    if (fp2 == NULL) {
        perror("fopen out2 failed");
        return 1;
    }

    // Run `ls -l` just as an example.
    pipe = popen("ls -l", "r");

    if (pipe == NULL) {
        perror("popen failed");
        return 1;
    }

    size_t nread, nwrote;
    char buf[N];

    while ((nread = fread(buf, 1, N, pipe))) {
        nwrote = 0;
        while (nwrote < nread)
            nwrote += fwrite(buf + nwrote, 1, nread - nwrote, fp1);

        nwrote = 0;
        while (nwrote < nread)
            nwrote += fwrite(buf + nwrote, 1, nread - nwrote, fp2);
    }

    pclose(pipe);
    fclose(fp2);
    fclose(fp1);

    return 0;
}

上面的代码只是对整个程序的工作方式给出一个粗略的估计,它不会检查popen(),fread上的一些错误等:当然,您应该检查最终程序中的错误。
还可以很容易地看到如何扩展它以支持任意数量的输出文件(仅使用fwrite数组)。

关于c - 可以多次复制文件描述符吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58078202/

10-11 23:06
查看更多