C:如何将stderr从System-command重定向到stdout或文件?

shell命令$ avrdude -c usbtiny文本输出到stderr。 我无法通过诸如head-less-more之类的命令来阅读它。它不是stdout。 我希望文本stdout或文件。 我怎么能用C做呢? 我试图通过我的上一个问题解决问题,但仍未解决。

我在OpenBSD中没有尝试过类似的东西,但至少在类似* nix的系统中,你可以使用dup2来做到这一点。

 #include  #include  int main(void) { fprintf(stderr, "This goes to stderr\n"); dup2(1, 2); //redirects stderr to stdout below this line. fprintf(stderr, "This goes to stdout\n"); } 

正常的方式是这样的:

 avrdude -c usbtiny 2>&1 

这通常指向stderr通常转到stdout。 如果您希望将其指向文件,则可以执行以下操作:

 avrdude -c usbtiny 2> outputfile.txt 

以下使用POSIX函数将标准输出文件编号复制到标准错误文件编号中。 将stderr复制到stdout在POSIX页面中给出dup2作为函数的示例用法。

 #include  #include  int main (void) { pid_t child = fork(); if (child == 0) { dup2(STDOUT_FILENO, STDERR_FILENO); execlp("avrdude", "-c", "usbtiny", NULL); } else if (child > 0) { waitpid(child); puts("Done!"); } else { puts("Error in forking :("); } return 0; } 

我需要以某种方式阻止C中的命令,这样我才能得到它的stderr

首先阅读man forkman exec如何启动子进程。 看看man 7 signalman sigactionman wait如何收获孩子。

最后, man dup2

未经测试的代码举例说明:

 int pip_stderr[2]; int r; int pid; r = pipe(pip_stderr); assert( r != -1 ); int pid = fork(); assert( pid != -1 ); if (pid == 0) { /* child */ /* child doesn't need to read from stderr */ r = close(pip_stderr[0]); assert( r != -1 ); /* make fd 2 to be the writing end of the pipe */ r = dup2(pip_stderr[1], 2); assert( r != -1 ); /* close the now redundant writing end of the pipe */ r = close(pip_stderr[1]); assert( r != -1 ); /* fire! */ exec( /* whatever */ ); assert( !"exec failed!" ); } else { /* parent */ /* must: close writing end of the pipe */ r = close( pip_stderr[1] ); assert( r != -1 ); /* here read from the pip_stderr[0] */ r = waitpid(pid,0,0); assert( r == pid ); } 

使用dup2(),我们用管道的写入端替换子节点的stderr(它是fd 2)。 在fork()之前调用pipe()。 在fork之后,我们还必须关闭管道的所有悬挂端,以便父进程中的读取实际上将接收EOF。

可能有一个更简单的解决方案使用stdio,但我不知道它。 由于popen()通过shell运行命令,可能有人可以告诉它将stderr重定向到stdout(并将stdout发送到/ dev / null)。 没试过。

也可以使用mktemp()( man 3 mktemp )创建临时文件名,使用system()命令将命令的stderr重定向到临时文件,并在system()返回后读取临时文件。