C: как перенаправить stderr от Системной команды до stdout или файла?

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

8
задан Community 23 May 2017 в 12:17
поделиться

4 ответа

Я не пробовал что-то подобное в 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");
}
17
ответ дан 5 December 2019 в 08:50
поделиться

Обычный способ будет выглядеть примерно так:

avrdude -c usbtiny 2>&1

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

avrdude -c usbtiny 2> outputfile.txt
3
ответ дан 5 December 2019 в 08:50
поделиться

В следующем примере функция 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;
}
0
ответ дан 5 December 2019 в 08:50
поделиться

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

Начните с чтения man fork , man exec о том, как запустить дочерний процесс. Посмотрите в человек 7 сигнал , человек в знак и человек ждет , чтобы узнать, как пожать ребенка.

Наконец, человек 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) дочернего элемента записывающим концом канала. pipe () вызывается перед fork (). После fork мы также должны закрыть все висящие концы конвейера, чтобы чтение в родительском процессе действительно получило EOF.

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

Также можно использовать mktemp () ( man 3 mktemp ) для создания имени временного файла, составить команду для system () для перенаправления stderr команды во временный файл и после возврата system () прочтите временный файл.

-1
ответ дан 5 December 2019 в 08:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: