前言

在我们使用system函数和exec族函数的时候,我们发现,我们没有办法获取到,执行之后的值。那么popen函数就解决了这个事情。

popen函数

popen函数是一个标准c库中的函数,可以用于打开一个进程来执行shell命令并返回文件指针,以便读取该命令的输出。

函数原型:

我们在终端使用man popen命令,查询到函数信息如下:

#include <stdio.h>

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

返回值

popen():  on  success,  returns a pointer to an open stream that can be
used to read or write to the pipe; if  the  fork(2)  or  pipe(2)  calls
fail, or if the function cannot allocate memory, NULL is returned.

popen函数在调用成功的时候则返回这个FILE结构体的指针,这个指针可以进行读写操作(fwrite fread等)。如果调用失败,则返回NULL。

参数说明

其中,command参数是要执行的命令,type参数则是指示打开文件的模式。type可以是“r”来获取命令的输出,也可以是“w”来向命令的输入传递数据。popen函数返回一个标准的文件流指针,可以使用这个指针来读取命令的输出或向命令的输入传递数据。

接下来我们使用一下这个函数:

#include <stdio.h>

int main()
{	
	FILE* fp;
	char str[1024];
	if((fp = popen("ls -l","r"))==NULL)
	{
		printf("popen faild\n");
	}
	fread(str,sizeof(char),sizeof(str),fp);
	printf("text:%s\n",str);
	fclose(fp);
	return 0;
}

上述示例中,程序使用popen来执行"ls -l"命令,并使用返回的文件指针来读取命令的输出,然后将输出打印到终端上。最后使用pclose来关闭文件指针。结果如下:

text:总计 80
-rw-rw-r-- 1 hyx hyx   328  3月 24 14:24 01fork.c
-rw-rw-r-- 1 hyx hyx   534  3月 24 14:59 02fork.c
-rw-rw-r-- 1 hyx hyx   535  3月 24 15:31 03vfork.c
-rw-rw-r-- 1 hyx hyx   621  3月 24 16:37 04wait.c
-rw-rw-r-- 1 hyx hyx   643  3月 24 17:41 05waitpid.c
-rw-rw-r-- 1 hyx hyx   139  3月 27 11:33 06system.c
-rw-rw-r-- 1 hyx hyx   143  3月 28 23:07 07text.c
-rw-rw-r-- 1 hyx hyx   217  3月 28 23:31 08execl.c
-rw-rw-r-- 1 hyx hyx   217  3月 29 00:00 09date.c
-rw-rw-r-- 1 hyx hyx   209  3月 29 00:11 10execlp.c
-rw-rw-r-- 1 hyx hyx   235  3月 29 00:27 11execvp.c
-rw-rw-r-- 1 hyx hyx   245  3月 29 14:19 11popen.c
-rwxrwxr-x 1 hyx hyx 16184  3月 29 14:19 a.out
-rwxrwxr-x 1 hyx hyx 15960  3月 28 23:09 test

需要注意的是,popen函数也可以用于将数据传递给外部命令。只需将mode参数设置为"w",然后将需要传递的数据写入文件指针即可。

我们可以使用一下:

#include <stdio.h>
#include <string.h>

int main()
{	
	FILE* fp;
	char *command =  "cat > output.txt";
	char str[1024];
	if((fp = popen(command,"w"))==NULL)
	{
		printf("popen faild\n");
	}
	fprintf(fp,"hello word\n");
	fprintf(fp,"this is some text write\n");
	fclose(fp);
	return 0;
}

在这个例子中,我们使用了cat > output.txt命令。

cat命令通常用于读取文件内容并将其输出到标准输出,但当我们使用>重定向时,它会从标准输入读取内容并将其写入到指定的文件中。因此,当我们使用popen以"w"模式打开这个命令时,我们可以向它写入数据,这些数据将被写入到output.txt文件中。

结果如下:

hyx@hyx-virtual-machine:~/c_project/c_Process$  cat output.txt  #我们查看一下生成的output.txt文件
hello word
this is some text write

总结

总结一下,popen函数在Linux环境下是一个非常有用的工具,能够方便地执行外部命令并处理命令的输入和输出。然而,在使用popen函数时,需要特别留意安全问题,并对输入进行适当的验证和处理。