執行shell命令的函數——system()、popen()

一、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


《完》

相關文章
相關標籤/搜索