2010-01-19 94 views
0

我想用系統()命令或EXECL執行命令,而想直接捕獲輸出在C.的緩衝器療法任何可能性利用DUP捕獲在緩衝器的輸出( )系統調用或使用管道()。我不想在使用mkstemp或任何其他臨時文件之間使用任何文件。請在此幫助我。提前感謝。我試圖用fork()創建兩個進程和管道輸出,它工作。但是我不想使用fork系統調用,因爲我要使用單獨的線程無限運行模塊,並且它調用了很多fork()和系統有時會耗盡資源。捕獲命令行輸出直接在緩衝器

要清楚我在做什麼是捕獲一個shell腳本的輸出緩衝處理輸出中,並在我所使用ncurses.Thankyou設計窗口中顯示它。

回答

0

如果你實現了一個C程序,並要執行一個腳本,你想用叉子()。除非你願意考慮在你的程序中嵌入腳本解釋器,否則你必須使用fork()(system()在內部使用fork()。

如果您正在運行資源不足,最有可能的,你是不是收穫你的孩子。在父進程獲得退出代碼之前,操作系統需要將孩子保持爲「殭屍」進程。你需要發出一個wait()調用來讓操作系統釋放與孩子相關的最終資源。

1

下面是用於捕獲程序的輸出一些代碼;它使用EXEC()的替代系統(),但是這是簡單的直接調用外殼,以適應:

How can I implement 'tee' programmatically in C?

void tee(const char* fname) { 
    int pipe_fd[2]; 
    check(pipe(pipe_fd)); 
    const pid_t pid = fork(); 
    check(pid); 
    if(!pid) { // our log child 
     close(pipe_fd[1]); // Close unused write end 
     FILE* logFile = fname? fopen(fname,"a"): NULL; 
     if(fname && !logFile) 
       fprintf(stderr,"cannot open log file \"%s\": %d (%s)\n",fname,errno,strerror(errno)); 
     char ch; 
     while(read(pipe_fd[0],&ch,1) > 0) { 
       //### any timestamp logic or whatever here 
       putchar(ch); 
       if(logFile) 
         fputc(ch,logFile); 
       if('\n'==ch) { 
         fflush(stdout); 
         if(logFile) 
           fflush(logFile); 
       } 
     } 
     putchar('\n'); 
     close(pipe_fd[0]); 
     if(logFile) 
       fclose(logFile); 
     exit(EXIT_SUCCESS); 
    } else { 
     close(pipe_fd[0]); // Close unused read end 
     // redirect stdout and stderr 
     dup2(pipe_fd[1],STDOUT_FILENO); 
     dup2(pipe_fd[1],STDERR_FILENO); 
     close(pipe_fd[1]); 
    } 
} 
0

你可以試試popen(),但你的基本的問題是運行過多的進程。你必須確保你的命令完成,否則你最終會遇到你遇到的問題。 popen()內部調用fork()反正(或效果,就好像它一樣)。

因此,最後,必須確保你想從你的線程運行的程序「很快」退出。

0

你想用這樣的順序:

Call pipe once per stream you want to create (eg. stdin, stdout, stderr) 
Call fork 
in the child 
    close the parent end of the handles 
    close any other handles you have open 
    set up stdin, stdout, stderr to be the appropriate child side of the pipe 
    exec your desired command 
    If that fails, die. 

in the parent 
    close the child side of the handles 
    Read and write to the pipes as appropriate 
    When done, call waitpid() (or similar) to clean up the child process. 

謹防阻擋和緩衝的。您不希望父進程在讀取時阻塞子進程時進行寫操作;確保使用非阻塞I/O或線程來處理這些問題。