Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:如何将stderr从系统命令重定向到stdout或文件?_C_Stdout_Stderr_File Descriptor - Fatal编程技术网

C:如何将stderr从系统命令重定向到stdout或文件?

C:如何将stderr从系统命令重定向到stdout或文件?,c,stdout,stderr,file-descriptor,C,Stdout,Stderr,File Descriptor,shell命令将文本输出到stderr。我不能用诸如headlessmore之类的命令来阅读它,因为它不是stdout。我希望文本是标准输出还是文件。我怎样用C语言来做呢?我曾试图用计算机解决这个问题,但仍未解决 通常的方式是: avrdude -c usbtiny 2>&1 avrdude -c usbtiny 2> outputfile.txt 这会将通常会转到stderr的内容改为转到stdout。如果希望将其定向到文件,可以执行以下操作: avrdude -c u

shell命令将文本输出到stderr。我不能用诸如headlessmore之类的命令来阅读它,因为它不是stdout。我希望文本是标准输出还是文件。我怎样用C语言来做呢?我曾试图用计算机解决这个问题,但仍未解决

通常的方式是:

avrdude -c usbtiny 2>&1
avrdude -c usbtiny 2> outputfile.txt
这会将通常会转到stderr的内容改为转到stdout。如果希望将其定向到文件,可以执行以下操作:

avrdude -c usbtiny 2>&1
avrdude -c usbtiny 2> outputfile.txt

我没有在OpenBSD中尝试过类似的方法,但至少在一些类似*nix的系统中,您可以使用
dup2
来实现这一点

#include <unistd.h>
#include <stdio.h>

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");
}
#包括
#包括
int main(void){
fprintf(stderr,“这到stderr\n”);
dup2(1,2);//将stderr重定向到此行下方的stdout。
fprintf(stderr,“这到stdout\n”);
}

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

#include <unistd.h>
#include <stdio.h>

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;
}
#包括
#包括
内部主(空)
{
pid_t child=fork();
如果(子项==0)
{
dup2(标准文件号、标准文件号);
execlp(“avrdude”、“-c”、“usbtiny”、NULL);
}
else if(子项>0)
{
waitpid(儿童);
放(“完成!”);
}
其他的
{
puts(“分叉错误:(”);
}
返回0;
}

我需要以某种方式阻止C中的命令,以便获得它的stderr

首先阅读有关如何启动子进程的
manfork
manexec
。了解如何获取子进程的
man7信号
mansigaction
manwait

最后是
人dup2

#include <unistd.h>
#include <stdio.h>

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");
}
未经测试的代码举例说明:

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(即fd2)替换为管道的写入端。管道()在fork()之前调用。在fork()之后,我们还必须关闭管道的所有悬挂端,以便父进程中的读取将实际接收EOF

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


还可以使用mktemp()(
man 3 mktemp
)创建临时文件名,为system()编写命令以将命令的stderr重定向到temp文件并在system()之后执行返回读取临时文件。

@user355926:在什么平台上?标准没有涵盖这一点,因此您需要一些不可移植的代码才能在C中执行。我需要以某种方式阻止C中的命令,以便获得其标准。还有两个类似的答案,但出于某种原因,他们似乎认为您需要分叉才能使用dup2。