C: Как перенаправить STDERR из System-Command на STDOUT или файл?

StackOverflow https://stackoverflow.com/questions/3019630

Вопрос

Команда оболочки $ avrdude -c usbtiny Выводит текст на STDERR. Я не могу прочитать его с коммуникациями, такими как головы - больше, потому что это не stdout. Я хочу текст stdout или файлу. Как я могу сделать это в C? Я пытался решить проблему мой последний вопрос Но все еще нерешено.

Это было полезно?

Решение

Я не пробовал что-то вроде этого в 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");
}

Другие советы

Обычный способ было бы чем-то вроде:

avrdude -c usbtiny 2>&1

Это направляет, что обычно поедет в Стдерр, чтобы вместо этого перейти на Stdout. Если вы предпочитаете направить его в файл, вы можете сделать что-то вроде:

avrdude -c usbtiny 2> outputfile.txt

Следующее используется функция POSIX для дублирования стандартного номера выходного файла в стандартный номер файла ошибок. Дублирование STDERR в STDOUT приведено на странице POSIX для dup2 в качестве примера использования функции.

#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;
}

Мне нужно как-то блокировать команду в C, чтобы я мог получить его STDERR

Начните с чтения man fork, man exec о том, как начать детский процесс. Заглянуть man 7 signal, man sigaction и man 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) ребенка с записью конца трубы. Труба () называется перед вилкой (). После формы мы также должны закрыть все висит Концы трубы, так что чтение в родительском процессе фактически получит EOF.

Вероятно, есть более простое решение с использованием Stdio, но я не знаю об этом. Поскольку POPEN () запускает команду через Shell, вероятно, можно сказать ему перенаправить STDERR в STDOUT (и отправить stdout на / dev / null). Никогда не пробовал это.

Можно также использовать mktemp () (man 3 mktemp) Чтобы создать имя файла TEMP, составить команду для системы () для перенаправления STDERR команды на файл TEMP, а после системы () возврата, прочитайте файл Temp.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top