【发布时间】:2016-04-09 18:24:33
【问题描述】:
我一直在尝试使用 dup2 进行简单的 i/o 重定向。我完全按照其他人所说的代码进行了操作,但仍然没有成功。
int out = open("stdoutput", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
dup2(out, 1);
printf("SEND TO FILE\n");
dup2(1, out);
close(out);
printf("BACK TO STANDARD OUT\n");
这会将 STANDARD OUT 打印到终端并 发送到文件 返回标准 到文件。为什么不切换回来?
我还想要一个 fork/exec 输出标准输出到一个文件。
int out2 = open("execout", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
dup2(out2, 1);
if(fork() == 0)
{
execvp("time", NULL);
perror(NULL);
}
dup2(out2, 1);
close(out2);
printf("BACK TO STANDARD OUT\n");
这会打印到终端:
标准 TERM_PROGRAM=Apple_Terminal:没有这样的文件或目录 0.00 真实 0.00 用户 0.00 系统
到文件执行,它会打印: 回归标准
exec 调用 time 似乎还有一些额外的问题(没有找到它,但仍然打印它?)但我的主要问题是 I/O 重定向无法正常工作。
提前感谢您的帮助。
更新:似乎有一个问题,具体是 exec 没有将输出发送到文件。代码:
int output_file = open("gcc_output", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if(fork() == 0)
{
dup2(output_file, 1);
close(output_file);
char *args[] = {"gcc", path, NULL};
printf("THIS GOES TO FILE");
execvp(args[0], args); // gcc output, errors etc. go to terminal
perror("exec");
exit(2);
}
exec 是否会导致它丢失文件描述符之类的?
【问题讨论】:
-
它不会切换回来,因为
out和1在第一个dup2调用之后是相同的,所以第二个dup2调用什么都不做。 -
值得检查您的
dup2调用结果以确认这一点。 -
在调用系统函数
dup2()和open()时,一定要检查返回值以保证操作成功。 -
exec 是否会导致它丢失文件描述符或其他内容? 不会,但您生成的命令可能会弄清楚如何将其输出发送到终端。在
strace -f -o /path/to/output/file /path/to/your/executable ...下运行您的可执行文件,以查看系统调用exec()'d 进程的内容。 (在fork()失败后调用exit()可能会导致各种问题 - 父母的退出处理程序的子副本被调用,父母的的子副本中的数据/i> IO 缓冲区被刷新到 parent 在fork()时打开的文件。请改用_exit()。)