【Linux】【开发】popen+fgets函数无法读取到命令输出的问题分析小结

popen及fgets使用基础

函数原型

#include <stdio.h>
FILE * popen ( const char * command , const char * type );
int pclose ( FILE * stream ); 
char *fgets(char *s, int size, FILE *stream);

功能说明

  • The popen() function shall execute the command specified by the string command. It shall create a pipe between the calling program and the executed command, and shall return a pointer to a stream that can be used to either read from or write to the pipe.
  • popen()会调用fork()产生子进程,之后,子进程中会调用/bin/sh -c来执行参数command的指令。
  • 参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,并返回一个文件指针。
  • 之后进程便可利用此文件指针,通过fgets等函数来读取子进程的输出设备或是写入到子进程的标准输入设备中。
    execl(shell path, “sh”, “-c”, command, (char *)0);
  • 此外,除了fclose()以外,所有使用文件指针(FILE*)操作的函数均可以使用。

代码示例

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fp;
    char buffer[128];

    // 使用 popen 执行 echo 命令
    fp = popen("echo Hello, World!", "r");
    if (fp == NULL) {
        perror("popen failed");
        return 1;
    }

    // 使用 fgets 从标准输出读取数据
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("Output: %s", buffer);
    }

    // 关闭管道
    pclose(fp);

    return 0;
}

使用场景

  • 在驱动开发过程中,经常有下面的需求:
    1)用户态执行某个命令;
    2)读取并解析该命令的输出;
    3)根据获取的参数值做进一步的处理。

常见的问题及分析

存在的问题

  • 有时,会出现命令在串口有输出,但是通过popen+fgets的方式,却读取不到任何数据。有的命令则没有这个问题。

不同命令的情况及处理方式

用户态输出的程序
  • 专有命令,如iwpriv、hostapd_cli等,均是在application中使用printf等函数进行输出;
  • 通用命令,如cat,也是在用户态进行输出:
cat /proc/sys/net/netfilter/nf_conntrack_max
  • 这种程序,使用前面的popen+fgets的方式是没有问题的。
内核态输出的程序
  • 还有一类程序,虽然是用户态程序,但会通过ioctl等进入内核,并在内核中通过printk进行串口输出。
  • 这种程序,使用前面的popen+fgets的方式是无法获取到命令输出的。
  • 对于这种程序,可做适当改造:
    – 通过ioctl进入内核,然后通过copy_to_user的方式,将内核数据copy到用户态;
    – 之后,可直接使用数据或在用户态输出均可。

小结

  • 关于两种命令的不同表现,大概原因是用户态输出的程序,使用的是标准输出,因此,popen的管道是可以连接过去的。而内核态输出的程序,使用的是printk,不是标准输出,因此,dup等函数对此无能为力。

如本文对你有些许帮助,欢迎大佬支持我一下(点赞+收藏+关注、关注公众号等),您的支持是我持续创作的竭动力
支持我的方式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花神庙码农

你的鼓励是我码字的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值