将输出redirect到C中的文件

我用C编写了一个基本的shell来执行基本的命令,它会执行命令lsls -alls -al | more ls -al | more等等

我想在我的shell中执行以下命令。 喜欢 ;

 ls -al > a.txt 

这会给我一个包含ls -al进程输出的a.txt文件。 我发现了一个解决scheme,它改变了我的shell中的命令,如[command1] | tee [filename] [command1] | tee [filename] 。 在这种情况下,它会将ls -al > a.txt更改为ls -al | tee a.txt ls -al | tee a.txt 。 但是这个过程也将输出传给文件和terminal。 如何停止在terminal打印输出。

还是有更好的解决scheme,而不是使用tee命令。 提前致谢…

Solutions Collecting From Web of "将输出redirect到C中的文件"

这是我用dup2测试的结果

更微妙的一点是记得在正确的时间fflush否则,你会得到非常令人惊讶的结果。

此外,更喜欢fileno而不是硬编码1 (标准输出) 2 (标准错误)。

重定向stdin留给读者一个练习

 #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> int main(int argc, const char *argv[]) { int out = open("cout.log", O_RDWR|O_CREAT|O_APPEND, 0600); if (-1 == out) { perror("opening cout.log"); return 255; } int err = open("cerr.log", O_RDWR|O_CREAT|O_APPEND, 0600); if (-1 == err) { perror("opening cerr.log"); return 255; } int save_out = dup(fileno(stdout)); int save_err = dup(fileno(stderr)); if (-1 == dup2(out, fileno(stdout))) { perror("cannot redirect stdout"); return 255; } if (-1 == dup2(err, fileno(stderr))) { perror("cannot redirect stderr"); return 255; } puts("doing an ls or something now"); fflush(stdout); close(out); fflush(stderr); close(err); dup2(save_out, fileno(stdout)); dup2(save_err, fileno(stderr)); close(save_out); close(save_err); puts("back to normal output"); return 0; } 

输出到文件时不要使用管道。

当你分叉孩子运行ls命令时,你注意到重定向,并打开文件; 然后使用dup2() (或close()dup() ),以便文件描述符现在是子级的标准输出; 您关闭重复的文件描述符 – 由open()返回的文件描述符; 然后像往常一样执行ls ; 其标准输出现在被发送到文件。

请注意,分叉之后执行非管道I / O重定向,而不是之前。 分叉之前必须先设置管道,但其他I / O重定向则不需要。

在新创建的进程中调用execve(2)执行命令之前,可以通过dup2(2)系统调用重定向其标准输入或输出:

 /* redirect stdout to a file */ dup2(1, some_open_file_descriptor); 

当然,你需要有一些错误处理。