您要问的是tee 命令存在的确切原因(您可以查看其源代码here)。
您不能多次使用dup2() 复制文件描述符。正如您已经看到的,最后一个会覆盖任何先前的重复。因此,您不能直接使用dup2() 将程序的输出重定向到多个文件。
为此,您确实需要多个描述符,因此您必须打开这两个文件,使用popen() 启动命令,然后从管道读取并写入这两个文件。
这里有一个非常简单的例子来说明如何做到这一点:
#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;
}
上面的代码只是粗略估计整个事情是如何工作的,它不会检查fread、fwrite等的一些错误:你当然应该在你的最终程序中检查错误.
还很容易看出如何扩展它以支持任意数量的输出文件(只需使用 FILE * 的数组)。