實現原理
strace 跟蹤結果:
clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x7fff936fc388) = 15661wait4(15661, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 15661
實際的過程:
1. 父進程 - clone() 一個子進程
2. 父進程 - wait4() 子進程退出(如果 SIGCHLD 處理方式為 SIG_DFL, 則阻塞等待指子進程退出;如果是 SIG_IGN, 則立馬返回 -1)
3. 子進程 - execl(/bin/sh -c command)
傳回值
傳回值可能的情況:
-1: system() 執行失敗,例如 clone() 失敗、wait4() 失敗(SIG_IGN 時返回 -1)
>=0: system() 執行成功,命令執行成功或失敗,通過 WEXITSTATUS() 擷取命令執行的返回碼
正確的使用方法
1. 處理 SIGCHLD 訊號
2. WIFEXITED() 和 WEXITSTATUS()
#include <errno.h>#include <string.h>#include <stdlib.h>#include <signal.h>#include <string>#include <iostream>int main(int argc, char* argv[]){ char cmd[] = "su www -c 'kdir -p -m 755 /data/inst-123456 &>/dev/null '"; sighandler_t old_sighandler = signal(SIGCHLD, SIG_DFL); int rv = system(cmd); signal(SIGCHLD, old_sighandler); if (-1 == rv) { std::cout << "error: " << strerror(errno) << std::endl; return -1; } std::cout << "return value: " << rv << std::endl; if (WIFEXITED(rv)) { std::cout << "subprocess exited, exit code: " << WEXITSTATUS(rv) << std::endl; if (0 == WEXITSTATUS(rv)) { // if command returning 0 means succeed std::cout << "command succeed" << std::endl; } else { if(127 == WEXITSTATUS(rv)) { std::cout << "command not found" << std::endl; return WEXITSTATUS(rv); } else { std::cout << "command failed: " << strerror(WEXITSTATUS(rv)) << std::endl; return WEXITSTATUS(rv); } } } else { std::cout << "subprocess exit failed" << std::endl; return -1; } return 0;}
命令後台執行
如果想命令在後台執行,可以在命令後面加 "&", 但是這樣做的後果是:只要 system() 執行成功,不管命令是否存在、命令執行是否成功,傳回值都為 0.
popen
http://blog.csdn.net/duyiwuer2009/article/details/50688493