Linux C - 获取shell命令返回结果 & 对结果应用场景的处理

本文介绍了在Linux环境下处理Shell命令返回结果的三种方法:使用临时文件、popen函数及匿名管道。并通过具体实例展示了如何提取和应用这些结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、获取shell命令返回结果

1.  方法一 :使用临时文件

  •     在Linux C中,执行shell命令,使用函数system;例如:system("ls -l");
## 举一个获取button gpio value的例子 ##
int get_button()
{
    	FILE *fp;
	int button = 1;
	char buf[512];

        system("cat /sys/class/gpio/gpio34/value > /tmp/button_value");
	fp = fopen("/tmp/button_value","rt");
	if(fp == NULL)
		return -1;
	fgets(buf,sizeof(buf),fp);          
	sscanf(buf,"%x",&button);       //sscanf的强大,简单的将字符串类型的变量转换为int型变量
	fclose(fp);
	return button;
}

将执行的命令结果重定向到文件;然后使用文件的基本操作,打开文件,获取命令执行结果。

值得一提的是,在上述举例中,我们的目的就是获取gpio value值,而存入文件中的正好也只是一个gpio value值。所以,在上述过程中,我们并没有需要在shell命令返回的结果buf中提取出我们自己想要的那个字符变量。

如果,我们的最终返回结果,是" 0xff800500  :  0xfffff437 ",而我想要的是第三个字符变量"0xfffff437",我又该怎么做呢?大家可以思考下。后面提取结果中的指定字符串中我会给出解决方法。

 

2. 方法二 : 使用popen函数

  •  popen创建一个管道,fork一个进程,然后执行shell;且shell的输出可以采用读取文件的方式获得。
### 举一个通过操作gpio寄存器来直接控制led灯亮的程序 ###
# 控制寄存器步骤:
# 读出指定地址寄存器值(dw) -> 按需修改寄存器值 -> 将寄存器值写入指定地址(sw)

int led_On(char *argv1,int n)
{
	FILE *fp = NULL;	
	char result[100] = {0}; 
	char data[100] = {0};
	int value = 0;
	char argv2[100] = {0};
	char buf1[100] = {0};
	char buf2[100] = {0};	
	
	sprintf(buf1,"dw %s",argv1);  
	fp = popen(buf1,"r");    //read reg value command
	if(NULL == fp)
	{
		return -1;
	}
	fread(result,sizeof(result),1,fp);  //save result - 本次cmd执行结果:0xff800500 : 0xfffff437
	getData(data,result,13,9);  //get needed data - 3年前的我想的是获取第13个字符往后的9个字符的方法;虽然有些笨,但好歹实现了。(笑~)
	sscanf(data,"%x",&value);   
	value |= (1<<n);   //set pin to high
	sprintf(argv2,"%x",value);
	sprintf(buf2,"sw %s %s",argv1,argv2); //write reg value cmd
	system(buf2);

	return 0;
}

 

3. 方法三 :使用匿名管道 ;

(但有了popen这么的简单的实现方法,这个了解下即可。)

 

二、对结果应用场景的处理

1. 提取结果中的指定字符串

  • 使用sscanf函数格式化取出各个字符串,能够轻易的实现指定字符串的提取。
## 以上述例子中的结果"0xff800500 : 0xfffff437"的举例 ##

#include <stdio.h>
 
int main()
{
    char buf[] = "0xff800500 : 0xfffff437";
    int address = 0, data = 0;
    char str[100] = {0};
    char dst_str[100] = {0};
    
    sscanf(buf,"%x %s %x",&address,str,&data);   //1.实现将0xfffff437取出,并转换为16进制数
    printf("address = %#x str = %s data = %#x\n",address,str,data);
    
    return 0;
}

sscanf函数真的很强大,详细可见Linux C语言中sscanf的详细用法

 

2. 比较结果中是否包含某个字符串

  • 看某个字符串中是否有某个子字符串,就用strstr函数
//check if set key flag it is PF=FFFFB
char *s = strstr(buf,"PF=FFFFB");
if( s != NULL)  //NULL - no substring
{
	printf("Get substring %s\n",s);
	printf("check key - OK!\n\n");
}

 

3. 有待补充......

 

三、后记

对于shell命令执行返回结果的处理场景还很多,待日后补充。

 

===========  小记  ============

Xia   2021.3.5 

1.今日惊蛰

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值