我一直在尝试使用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 real 0.00 user 0.00 sys
和文件execout,它打印: 回到标准输出
exec调用时间似乎有一些额外的问题(没有找到它但是然后打印它?)但我的主要问题是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会导致它丢失文件描述符吗?
答案 0 :(得分:0)
dup2(from, to)
将文件描述符from
复制到文件描述符to
;如果to
已打开,则会在被覆盖之前以静默方式关闭。
在您的第一个示例中,您打开文件stdoutput
进行写入;给出最低可能的描述符号(可能是3);然后你的dup2(out2, 1)
将这个描述符复制到标准输出描述符1上;原始标准输出静默关闭。现在有4个开放描述符:
stdoutput
stdoutput
最后,您尝试通过在文件描述符3上复制文件描述符1来“恢复”原始标准输出。
相反,您应该通过dup
将原始标准输出存储到另一个文件描述符中:
int out = open("stdoutput", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
int saved_stdout = dup(1); // create a copy of the stdout file descriptor
dup2(out, 1);
close(out); // close the extra descriptor
printf("SEND TO FILE\n");
dup2(saved_stdout, 1); // copy the saved stdout file descriptor to 1
close(saved_stdout); // close the copy of stdout
printf("BACK TO STANDARD OUT\n");
你的execvp
电话也被打破了;应该有一个额外的参数,即命令名称;同时time
不打印当前日期,但是是一个命令,它将另一个命令作为参数 - 也许你想要执行date
命令?此外,您希望在fork之后在子进程中执行dup2
。请尝试以下方法:
int out2 = open("execout", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
if (fork() == 0) {
dup2(out2, 1);
close(out2);
execvp("date", "date", (char *)NULL);
perror("exec");
exit(2);
}
close(out2);
printf("STILL POINTING TO STANDARD OUT\n");