popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。这个进程必须由 pclose() 函数关闭,而不是 fclose() 函数。pclose() 函数关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态。如果 shell 不能被执行,则 pclose() 返回的终止状态与 shell 已执行 exit 一样。
1 int shexec(const char *cmd, char res[][512], int count) 2 { 3 printf("shexec, cmd: %s\n", cmd); 4 5 FILE *pp = popen(cmd, "r"); 6 if(!pp) { 7 printf("error, cannot popen cmd: %s\n", cmd); 8 return -1; 9 } 10 int i = 0; 11 char tmp[512]; 12 while(fgets(tmp, sizeof(tmp), pp) != NULL) { 13 if(tmp[strlen(tmp)-1] == '\n') { 14 tmp[strlen(tmp)-1] = '\0'; 15 } 16 printf("%d.get return results: %s\n", i, tmp); 17 strcpy(res[i], tmp); 18 i++; 19 if(i >= count) { 20 printf("Too many results, return\n"); 21 break; 22 } 23 } 24 25 pclose(pp); 26 27 return i; 28 }
popen不能返回shell执行错误的结果,可以通过把cmd命令的error信息输出到文件来获取执行状态。
char cmd[64]; char res[10][512]; strcpy(cmd, "ls -l 2> err"); int cnt = shexec(cmd, res, 10);
解析err文件的内容可以得到执行命令失败的状态。