popen() 函數通過創建一個管道,調用 fork 產生一個子進程,執行一個 shell 以運行命令來開啟一個進程。這個進程必須由 pclose() 函數關閉,而不是 fclose() 函數。pclose() 函數關閉標准 I/O 流,等待命令執行結束,然后返回 shell 的終止狀態。如果 shell 不能被執行,則 pclose() 返回的終止狀態與 shell 已執行 exit 一樣。
pclose返回成功后,可以通過 WIFEXITED, WEXITSTATUS 來獲取所執行命令的返回值。
1 //execute shell command 2 int shexec(const char *cmd, char res[][512], int count) 3 { 4 printf("shexec, cmd: %s\n", cmd); 5 6 FILE *pp = popen(cmd, "r"); 7 if(!pp) { 8 printf("error, cannot popen cmd: %s\n", cmd); 9 return -1; 10 } 11 int i = 0; 12 char tmp[512]; 13 while(fgets(tmp, sizeof(tmp), pp) != NULL) { 14 if(tmp[strlen(tmp)-1] == '\n') { 15 tmp[strlen(tmp)-1] = '\0'; 16 } 17 printf("%d.get return results: %s\n", i, tmp); 18 strcpy(res[i], tmp); 19 i++; 20 if(i >= count) { 21 printf("get enough results, return\n"); 22 break; 23 } 24 } 25 26 int rv = pclose(pp); 27 printf("ifexited: %d\n", WIFEXITED(rv)); 28 29 if (WIFEXITED(rv)) 30 { 31 printf("subprocess exited, exit code: %d\n", WEXITSTATUS(rv)); 32 } 33 34 return i; 35 }
popen不能返回shell執行錯誤的結果,可以通過把cmd命令的error信息輸出到文件來獲取執行狀態。
char cmd[64]; char res[10][512]; strcpy(cmd, "ls -l 2> err"); int cnt = shexec(cmd, res, 10);
解析err文件的內容可以得到執行命令失敗的狀態。