栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C/C++ 手撸linux终端程序

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C/C++ 手撸linux终端程序

系列文章目录

文章目录

系列文章目录前言一、popen()函数介绍二、使用步骤

1.头文件2.函数定义3.使用示例4.注意事项 三、总结


前言

在使用linux系统时,我们经常会使用终端命令执行一些系统命令,比如查看文件夹目录文件“ls -lha”,查看磁盘情况“df -h”,这些命令我们经常使用,那么问题来了,这种效果能使用程序模拟出来吗,手撸一个终端程序怎么样!

本节主要接收popen函数的使用。

一、popen()函数介绍

 popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c来执行参数command的指令。参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。

二、使用步骤

 type参数只能是读或者写中的一种,得到的返回值(标准I/O流)也具有和type相应的只读或只写类型。如果type是"r"则文件指针连接到command的标准输出;如果type是"w"则文件指针连接到command的标准输入。
  command参数是一个指向以NULL结束的shell命令字符串的指针。这行命令将被传到bin/sh并使用-c标志,shell将执行这个命令。
popen()的返回值是个标准I/O流,必须由pclose来终止。前面提到这个流是单向的(只能用于读或写)。向这个流写内容相当于写入该命令的标准输入,命令的标准输出和调用popen()的进程相同;与之相反的,从流中读数据相当于读取命令的标准输出,命令的标准输入和调用popen()的进程相同。

1.头文件

使用时需要引入头文件:

#include 
2.函数定义

 popen函数还创建一个管道用于父子进程间通信。父进程要么从管道读信息,要么向管道写信息,至于是读还是写取决于父进程调用popen时传递的参数。
定于如下:

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

参数一:要执行的命令;
参数二:操作类型,读(r)/写(w);
返回值:如果调用fork()或pipe()失败,或者不能分配内存将返回NULL,否则返回标准I/O流。popen()没有为内存分配失败设置errno值。如果调用fork()或pipe()时出现错误,errno被设为相应的错误类型。如果type参数不合法,errno将返回EINVAL。

3.使用示例
#include 
#define CMD_MAX_LENS 256*100

static int GetCmdResult(const char* strCmd, char* strResult, unsigned int nSize)
{
	if(strCmd == NULL || strResult == NULL)
		return -1;
	
	if(strResult)
	{
		FILE *fd;
		unsigned int ch,i;

		if((fd = popen(strCmd, "r")) == NULL)
		{
			printf("ERROR: get_system(%s)", strCmd);
			return -1;
		}
		for(i=0; i 

执行make,然后运行程序,结果打印为:

$ ./main.out 
cmd response:
文件系统        容量  已用  可用 已用% 挂载点
udev             16G     0   16G    0% /dev
tmpfs           3.2G   17M  3.2G    1% /run
/dev/sdb4       226G   53G  162G   25% /
tmpfs            16G  4.0K   16G    1% /dev/shm
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
tmpfs            16G     0   16G    0% /sys/fs/cgroup
/dev/sdb2       457M  249M  175M   59% /boot
/dev/sdb1       487M  5.3M  481M    2% /boot/efi
/dev/loop10     163M  163M     0  100% /snap/gnome-3-28-1804/145
/dev/loop11      55M   55M     0  100% /snap/snap-store/558
/dev/loop12      51M   51M     0  100% /snap/snap-store/547
/dev/loop15      66M   66M     0  100% /snap/gtk-common-themes/1519
/dev/sda1       2.7T  1.8T  400G   60% /home
/dev/loop2      249M  249M     0  100% /snap/gnome-3-38-2004/99
/dev/loop17      44M   44M     0  100% /snap/snapd/14978
/dev/loop1       62M   62M     0  100% /snap/core20/1361
none             16G  164K   16G    1% /run/qemu
4.注意事项

 (1)popen()函数通过创建一个管道,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。这个管道必须由pclose()函数关闭,而不是fclose()函数。pclose()函数关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。如果shell不能被执行,则pclose()返回的终止状态与shell已执行exit一样。
(2)在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。

三、总结

 本节主要对popen函数进行了讲解,对函数的定义,使用方式和调用关系做了整理,有不对的地方希望读友能够指出。
本节示例的代码编译测试提供给大家popen用法示例,也希望大家能够验证一下。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/783913.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号