"
popen和system都可以执行外部命令。
popen相当于是先创建一个管道,fork,关闭管道的一端,执行exec,返回一个标准的io文件指针。
system相当于是先后调用了fork, exec,waitpid来执行外部命令
popen本身是不阻塞的,要通过标准io的读取使它阻塞
system本身就是阻塞的。
最近写的程序,要求进程在调用的外部命令运行完毕之后,再继续 向下进行。
一开始调用的popen,然后只是用了fgetc,使其阻塞,但是总是阻塞不了。原因就是如果外部命令有很多的输出内容,那fgets在得到输出的第一个字符的时候就返回了,不在阻塞了;调用fread,如果size和nitems设置的不够大,也是一样的问题。比如//代码效果参考:https://v.youku.com/v_show/id_XNjQwMDE0OTE1Mg==.html
外部命令要输出100个字符,结果size是sizeof(char),nitems是10,那么当fread读到地10个字符的时候,就已经满足条件了,就返回了。正确的方法是调用system,因为system最后会调用waitpid,来等待子进程运行完毕。
其实可以调用pclose来阻塞
下面看一下代码示例:
test_log:
?1234567891011121314#include #include#include int main(void){ int t = 20; while(t-- > 0) { sleep(1); fprintf(stdout, ""run test log %d\n"", t); fflush(stdout); //这里不flush的话,popen可能无法实时读到这里输出的内容 } return 0;}
popen使用示例:
?1234567891011121//代码效果参考:https://v.youku.com/v_show/id_XNjQwNjU5MTQxMg==.html
31415161718192021int main(void){ char buf【LOG_MAX_PER_LEN】; FILE* fp = popen(""test_log"", ""r""); if(fp) { printf(""open success\n""); while(fgets(buf, LOG_MAX_PER_LEN, fp) != NULL) { if(buf【strlen(buf) - 1】 == '\n') { buf【strlen(buf) - 1】 = '\0'; } fprintf(stdout, ""【test log output】: %s\n"", buf); } } else { perror(""popen fail!\n""); return -1; } int ret = pclose(fp); printf(""pclose ret %d\n"", ret); return 0;}"
