2009-11-21 67 views
4

我使用的execl功能當我運行從下一個Linux進程,例如趕上輸出中:如何從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()之後的任何代碼永遠不會執行,除非它失敗。

如果要捕獲shell命令的輸出,則需要popen

+0

+1對於提及popen() – 2009-11-22 19:13:17

5

首先,execl不會返回,除非存在未找到可執行文件的問題。 sleep(4)可能永遠不會執行。

至於重定向和獲取輸出,請查看Unix Programming FAQ。尋找spawn_background_command

4

要做到這一點,你需要打開一個管道。然後,用管道的寫入結束替換孩子的stdout,並從父級管道的讀取結束讀取。就像您的代碼的這個修改版本:

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

好的工作正確清理管道 - 很少有正確的。 – 2009-11-22 19:15:10

+0

我這樣做,但它只工作完全當我切換行'wait()'並將它放在'fgets()',任何解釋? – 2013-08-12 16:18:15

+0

@mf_:這應該沒有什麼區別 - 你在使用什麼操作系統? – caf 2013-08-12 21:55:38