一、FILE* popen(const char* cmd,const char* type);html
int pclose(FILE* stream);
shell
popen()函數fork()一個子進程,建立管道用於父子進程間通訊,父進程要麼從管道讀,要麼往管道寫,執行一個shell以運行命令來開啓一個進程bash
相比於system()的又是在於使用簡單,popen()只返回兩個值,成功返回子進程的status,失敗返回-1
ide
二、int system(const char* cmd);函數
處理了fork()、execl()、waitpid()這些細節,還有一些信號
htm
一、這個庫函數使用fork()建立一個子進程來;blog
二、子進程調用/bin/sh-c cmd執行指定的參數命令(/bin/sh通常是一個軟鏈接,指向某個具體的shell,好比bash,-c選項告訴shell從字符串cmd中讀取命令),執行完以後返回調用原進程;
繼承
三、父進程調用waitpid等待子進程結束。進程
執行命令時SIGCHLD將被阻塞,在調用system()的進程中SIGINT和SIGQUIT將被忽略。
字符串
返回值:
若是cmd是NULL,返回非0,通常爲1;
若是fork()失敗,即子進程沒法被建立,返回-1;
若是shell在子進程中不能被替換,即execl()失敗,返回127;
若是全部系統調用成功了,子進程執行cmd命令,但cmd命令不必定執行成功,返回cmd經過exit或return返回的值;
system()源碼:
int system(const char * cmdstring) { pid_t pid; int status; if(cmdstring == NULL) { return (1); //若是cmdstring爲空,返回非零值,通常爲1 } if((pid = fork())<0) { status = -1; //fork失敗,返回-1 } else if(pid == 0) { execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); _exit(127); // exec執行失敗返回127,注意exec只在失敗時才返回如今的進程,成功的話如今的進程就不存在啦~~ } else //父進程 { while(waitpid(pid, &status, 0) < 0) { if(errno != EINTR) { status = -1; //若是waitpid被信號中斷,則返回-1 break; } } } return status; //若是waitpid成功,則返回子進程的返回狀態 }
system()會繼承環境變量,編寫具備SUID/SGID權限的程序時不要用這個函數
建議system()只用來執行shell命令
建議監控一下system()函數執行完畢以後的errno值
建議使用popen()代替system()
http://blog.sina.com.cn/s/blog_8043547601017qk0.html
《完》