2009-11-21 2 views
4

Я использую функцию execl, чтобы запустить процесс Linux из C. Когда я, например:Как поймать вывод из execl команды

int cmd_quem() { 
    int result; 
    result = fork(); 
    if(result < 0) { 
    exit(-1); 
    } 

    if (result == 0) { 
    execl("/usr/bin/who", "who", NULL); 
    sleep(4); //checking if father is being polite 
    exit(1); 
    } 
    else { 
    // father's time 
    wait(); 
    } 

    return 0; 
} 

я получаю на консоли результата делает «кто» на терминале. Я хотел бы знать, есть ли какая-либо функция «поймать» результат вывода из команды. То, что я имею в виду, если есть в любом случае, чтобы поймать это:

feuplive tty5   2009-11-21 18:20 

Что одна из линий, полученных от кто командует.

ответ

2

Семейство функций exec() создает новый образ процесса из обычного исполняемого файла. Этот файл является либо исполняемым объектным файлом, либо скриптом интерпретатора. От успешного вызова функции exec() нет возврата, потому что вызывающий процесс функционально заменяется новым процессом.

Таким образом, любой код после exec() никогда не выполняется, если он не был выполнен.

Если вы хотите захватить вывод команды оболочки, вам понадобится popen.

+0

+1 за упоминание POPEN() –

5

Во-первых, execl не возвращается, если не существует проблемы, так как исполняемый файл не найден. То, что sleep(4), вероятно, никогда не выполняется.

Что касается перенаправления и получения вывода, ознакомьтесь с Unix Programming FAQ. Ищите spawn_background_command.

4

Для этого вам необходимо открыть трубу. Затем вы заменяете стандартный вывод ребенка на конец записи в трубе и читаете с конца чтения в канале родителя. Как это модифицированная версия коды:

int cmd_quem(void) { 
    int result; 
    int pipefd[2]; 
    FILE *cmd_output; 
    char buf[1024]; 
    int status; 

    result = pipe(pipefd); 
    if (result < 0) { 
    perror("pipe"); 
    exit(-1); 
    } 

    result = fork(); 
    if(result < 0) { 
    exit(-1); 
    } 

    if (result == 0) { 
    dup2(pipefd[1], STDOUT_FILENO); /* Duplicate writing end to stdout */ 
    close(pipefd[0]); 
    close(pipefd[1]); 

    execl("/usr/bin/who", "who", NULL); 
    _exit(1); 
    } 

    /* Parent process */ 
    close(pipefd[1]); /* Close writing end of pipe */ 

    cmd_output = fdopen(pipefd[0], "r"); 

    if (fgets(buf, sizeof buf, cmd_output)) { 
    printf("Data from who command: %s\n", buf); 
    } else { 
    printf("No data received.\n"); 
    } 

    wait(&status); 
    printf("Child exit status = %d\n", status); 

    return 0; 
} 
+0

Хорошей работы по очистке сантехники правильно - так мало, чтобы это право. –

+0

Я сделал это, но он работал только полностью, когда я переключил строку 'wait()' и поместил ее перед 'fgets()', любое объяснение? –

+0

@mf_: Это не должно иметь значения - какую ОС вы используете? – caf

Смежные вопросы