Linux 在 C 中,如何在进行 execvp() 或类似调用时将 stdin/stdout/stderr 重定向到文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14543443/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In C how do you redirect stdin/stdout/stderr to files when making an execvp() or similar call?
提问by Matt
I have the following code:
我有以下代码:
pid_t pid = fork();
if (pid == -1)
{
// ...
}
else if (pid == 0)
{
stdin = someopenfile;
stdout = someotherfile;
stderr = somethirdopenfile;
execvp(args[0], args);
// handle error ...
}
else
{
// ...
}
The problem is, the input/output of the execvp()
call is still the console, rather than the files. Clearly I am doing something wrong, what is the right way to do this?
问题是,execvp()
调用的输入/输出仍然是控制台,而不是文件。显然我做错了什么,这样做的正确方法是什么?
采纳答案by caf
The right way to do it is to replace the file descriptors STDIN_FILENO
, STDOUT_FILENO
and STDERR_FILENO
with the opened files using dup2()
. You should also then close the original files in the child process:
正确的做法是替换文件描述符STDIN_FILENO
,STDOUT_FILENO
并STDERR_FILENO
使用dup2()
. 您还应该关闭子进程中的原始文件:
else if (pid == 0)
{
dup2(fileno(someopenfile), STDIN_FILENO);
dup2(fileno(someotherfile), STDOUT_FILENO);
dup2(fileno(somethirdopenfile), STDERR_FILENO);
fclose(someopenfile);
fclose(someotheropenfile);
fclose(somethirdopenfile);
execvp(args[0], args);
// handle error ...
}
回答by Hyman
Take a look at freopen
function.
看看freopen
功能。
I had to do something similar with stdout
and wrote two functions that do the work for me:
我不得不做类似的事情,stdout
并编写了两个为我完成工作的函数:
static int fd;
static fpos_t pos;
void switchStdout(const char *newStream)
{
fflush(stdout);
fgetpos(stdout, &pos);
fd = dup(fileno(stdout));
freopen(newStream, "w", stdout);
}
void revertStdout()
{
fflush(stdout);
dup2(fd, fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos);
}
回答by alhelal
You can use this when stdin , stdout , stderr are terminal-
当 stdin 、 stdout 、 stderr 是终端时,您可以使用它
//change stdin,stdout,stderr
freopen("new_stdin","r",stdin);
freopen("new_stdout","r",stdout);
freopen("new_stderr","r",stderr);
//----do something;
//reset stdin,stdout,stderr
freopen("/dev/tty","r",stdin);
freopen("/dev/tty","r",stdout);
freopen("/dev/tty","r",stderr);