网站首页 > 技术文章 正文
popen 函数用于创建一个管道来与一个进程通信。这个函数允许你在 C 程序中执行一个 shell 命令,并根据指定的模式读取命令的输出或向命令发送输入。
语法
FILE *popen(const char *command, const char *type);
- command: 要在 shell 中执行的命令。
- type: 模式,可以是:
"r": 读取命令的输出。
"w": 向命令写入输入。
返回值
返回一个 FILE * 指针,可以用标准文件 I/O 函数(如 fgets、fprintf 等)来操作。
如果操作失败,返回 NULL。
工作原理
内部实现: popen 的内部操作包括:
- 创建一个管道(单向通信通道)。
- 通过 fork 创建一个子进程。
- 子进程执行指定的 shell 命令。
- 父进程返回一个连接到管道的 FILE * 指针。
应用场景
1. 捕获命令输出
你可以使用 popen 执行一个 shell 命令,并直接在你的 C 程序中捕获其输出。
示例: 列出当前目录中的文件。
#include <stdio.h>
int main() {
FILE *pipe = popen("ls -l", "r");
char buffer[128];
if (pipe == NULL) {
perror("popen 失败");
return 1;
}
while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
printf("%s", buffer);
}
pclose(pipe);
return 0;
}
使用注意事项
资源管理: 始终使用 pclose 关闭由 popen 打开的管道,以避免资源泄漏。
安全性: 对于 command 字符串,特别是包含用户输入的情况,要小心 shell 注入漏洞。
一个实例介绍(部分代码):
snprintf(cmd, sizeof(cmd), "sudo lsusb -d %x:%x", MCU_VENDOR_ID, MCU_PRODUCT_ID);
FILE *lsusb_pipe = popen(cmd, "r");
if (lsusb_pipe == NULL)
{
rc = -1;
goto Exit;
}
while (fgets(line, sizeof(line), lsusb_pipe) != NULL && index < MAX_DEVICES)
{
char bus[10], device[10];
if (sscanf(line, "Bus %s Device %s", bus, device) == 2)
{
sprintf(devices[index], "/dev/bus/usb/%s/%s", bus, device);
index++;
}
}
构建的命令是 sudo lsusb -d <MCU_VENDOR_ID>:<MCU_PRODUCT_ID>,用于根据指定的厂商和产品 ID 过滤 USB 设备。
- 代码使用 fgets 函数逐行读取 lsusb 命令的输出。
每行内容都会检查是否符合预期格式("Bus <bus> Device <device>"),如果符合,则使用 sscanf 提取出总线和设备编号。
- 提取出的总线和设备编号随后被用来构建 USB 设备文件的路径,并存储在 devices 数组中。
猜你喜欢
- 2024-09-12 c++ printf 到 std::cout(c++怎么用printf输出整数)
- 2024-09-12 C 语言未初始化的局部变量是多少?
- 2024-09-12 大话C语言:函数(c语言函数视频讲解)
- 2024-09-12 每日一题||C语言刷题(c语言刷题网)
- 2024-09-12 大话C语言:逗号运算符及运算法优先级
- 2024-09-12 C语言学习篇(14)-----sizeof运算符
- 2024-09-12 C语言 include的用法(c语言include的用法与搭配)
- 2024-09-12 C语言的位运算基本操作演示(c语言位运算的运算规则)
- 2024-09-12 编写一个C程序,输入a,b,c三个值,输出其中最大值
- 2024-09-12 C语言如何实现大数相加(c语言大数相加思路)
- 1522℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 641℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 527℃MySQL service启动脚本浅析(r12笔记第59天)
- 492℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 492℃启用MySQL查询缓存(mysql8.0查询缓存)
- 479℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 461℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 459℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)