1.popen
popen相当于是先创建一个管道,fork,关闭管道的一端,执行exec,返回一个标准的io文件指针。
因为popen通过管道新开shell,执行命令,所以本身是不阻塞的,要通过标准io的读取使它阻塞。
FILE * popen ( const char * command , const char * type );
type 参数只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 "r" 则文件指针连接到 command 的标准输出;如果 type 是 "w" 则文件指针连接到 command 的标准输入。
注意:popen的第二个参数会将标准输出或者标准输入的数据流传入FILE*的流中。也就是这个时候调用fread只会读取command的数据。例如:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
FILE *fp = NULL;
char array[1024] = {'\0'};
fp = popen("ifconfig -a", "r");
printf("1111111111111111111111111111111111\n");
fread(array, 1, 1024, fp);
printf("------------------------------\n");
printf("%s",array);
fclose(fp);
return 0;
}
结果:
1111111111111111111111111111111111------------------------------
enp2s0:
...
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
.....
所以fread会读取popen中command输出的数据。
注意:由于popen不是阻塞的,如果执行的脚本耗时比较长,可能会在shell脚本执行完之前,调用fclose,导致popen命令执行失败。
2.system
system()函数执行过程:
1.fork一个子进程;
2.在子进程中调用exec函数去执行command;
3.在父进程中调用wait去等待子进程结束。
由于system没有新开shell,执行system的随后会调用waitpid,来等待子进程运行完毕,所以会阻塞的。
#include <cstdlib>
int main()
{
system("ifconfig -a");
return 0;
}
结果:
enp2s0:
...
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
.....
可见system的输出不需要单独接收,会直接在终端打印,因为这个进程实际是在同一个终端执行的。