1. 程式人生 > 其它 >《popen和system的區別》

《popen和system的區別》

popen和system都可以執行外部命令。 popen相當於是先建立一個管道,fork,關閉管道的一端,執行exec,返回一個標準的io檔案指標。 system相當於是先後呼叫了fork, exec,waitpid來執行外部命令 popen本身是不阻塞的,要通過標準io的讀取使它阻塞 system本身就是阻塞的。    
FILE * popen ( const char * command , const char * type );
  type 引數只能是讀或者寫中的一種,得到的返回值(標準 I/O 流)也具有和 type 相應的只讀或只寫型別。如果 type 是 "r" 則檔案指標連線到 command 的標準輸出;如果 type 是 "w" 則檔案指標連線到 command 的標準輸入。   注意:popen的第二個引數會將標準輸出或者標準輸入的資料流傳入FILE*的流中。也就是這個時候呼叫fread只會讀取command的資料。   eg:
#include <stdio.h>
#include 
<unistd.h> int main(void) { FILE *fp = NULL; char array[1024] = {'\0'}; fp = popen("ifconfig -a", "r"); printf("1111111111111111111111111111111111\n"); fread(array, 1, 1024, fp); printf("------------------------------\n"); printf("%s",array); fclose(fp);
return 0; }

結果:

1111111111111111111111111111111111

------------------------------ enp2s0: ... lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 .....

  所以不用擔心fread會讀取popen中command輸出資料以外的資料。

    最近寫的程式,要求程序在呼叫的外部命令執行完畢之後,再繼續 向下進行。 一開始呼叫的popen,然後只是用了fgetc,使其阻塞,但是總是阻塞不了。原因就是如果外部命令有很多的輸出內容,那fgets在得到輸出的第一個字元的時候就返回了,不在阻塞了;呼叫fread,如果size和nitems設定的不夠大,也是一樣的問題。比如外部命令要輸出100個字元,結果size是sizeof(char),nitems是10,那麼當fread讀到地10個字元的時候,就已經滿足條件了,就返回了。 正確的方法是呼叫system,因為system最後會呼叫waitpid,來等待子程序執行完畢。