扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

嵌入式开发,高效修改配置文件的技巧

03/26 10:14
230
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

大家好,我是杂烩君。

嵌入式开发中,修改配置文件是一个高频操作。比如切换 WiFi 热点、调整串口波特率、更新服务器地址……这些参数往往分散在各种配置文件中。

今天就来分享一种简洁高效的配置文件修改方法——借助 sed 工具,一行命令搞定,还能轻松集成到 C 代码中。

一、常见配置文件格式及其局限

平时我们接触到的配置文件,大致分为两类:

标准格式:如 JSON、INI、XML、YAML 等。这些格式都有成熟的解析库,例如 C 语言中的 cJSON、iniparser 等,使用起来比较方便。

非标准格式:很多开源组件或系统工具使用的配置文件并不遵循上述标准格式,而是采用自定义的 key=value 或其他自由格式。例如 Linux 下常见的 wpa_supplicant.confhostapd.confresolv.conf 等,格式各异,没有通用的解析库可用。

对于非标准格式的配置文件,我们当然可以自己写解析代码——打开文件、逐行读取、字符串匹配、替换、写回文件。但这套流程写下来代码量不小,而且容易出 bug。

有没有更优雅的方式?有,那就是 sed

二、sed 工具简介

sed(Stream Editor)是 Linux 下一个强大而轻量的流式文本编辑器,可以对文本进行查找、替换、删除、插入等操作,而无需打开文件进行交互式编辑。

sed 最常用的功能就是文本替换,其基本语法为:

sed -i 's/原始内容/替换内容/g' 文件路径

各参数含义:

参数 说明
-i 直接修改源文件(in-place),不加此参数则只输出结果,不改原文件
s 替换(substitute)命令
/ 分隔符,用于分隔匹配模式和替换内容
g 全局替换(global),一行中有多个匹配时全部替换

理解了基本语法,我们来看一个嵌入式开发中的实战案例。

三、实战:修改 WiFi 配置文件

如修改 WiFi 配置文件 wpa_supplicant.conf

ctrl_interface=/var/run/wpa_supplicant
update_config=1
ap_scan=1

network={
        ssid="test"
        psk="12345678"
        scan_ssid=1
        key_mgmt=WPA-PSK
        priority=1
}

现在我们需要将 ssid 修改为 **LinuxZn**,psk 修改为 **88888888**。

3.1 命令行操作

sed -i 's/ssid="[^"]*"/ssid="LinuxZn"/g' ./wpa_supplicant.conf
sed -i 's/psk="[^"]*"/psk="88888888"/g' ./wpa_supplicant.conf

3.2 正则表达式解析

这里的核心在于匹配模式 ssid="[^"]*",我们逐层拆解

ssid=" :匹配字面量

ssid="[^"]* :这是一个正则表达式,[^"] 表示匹配除双引号以外的任意字符* 表示匹配零次或多次。组合起来就是匹配双引号之间的任意内容

" :匹配结尾的双引号

所以 ssid="[^"]*" 能够匹配到 ssid="test"ssid="MyWiFi" 等任意 ssid 值,然后用 ssid="LinuxZn" 进行替换。psk 字段同理。

这种写法的好处是:无论原来的值是什么,都能正确匹配并替换,具有良好的通用性。

四、在 C 代码中集成 sed

在嵌入式 Linux 应用中,我们往往需要在程序运行时动态修改配置。可以通过 system() 函数调用 sed 命令来实现:

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

#define SHELL_CMD_MODIFY_WIFI_SSID     "sed -i 's/ssid="[^"]*"/ssid="%s"/g' ./wpa_supplicant.conf"
#define SHELL_CMD_MODIFY_WIFI_PSW      "sed -i 's/psk="[^"]*"/psk="%s"/g' ./wpa_supplicant.conf"
#define SHELL_CMD_RESET_WIFI_CONF      "cp default_wpa_supplicant.conf wpa_supplicant.conf"

static int modify_wifi_config(const char *ssid, const char *password)
{
    char shell_cmd[256] = {0};
    int ret = 0;

    /* 重置WiFi配置文件,保证格式正确 */
    ret = system(SHELL_CMD_RESET_WIFI_CONF);
    if (ret != 0) 
    {
        printf("reset wifi config failed!n");
        return-1;
    }

    /* 修改WiFi名称 */
    snprintf(shell_cmd, sizeof(shell_cmd), SHELL_CMD_MODIFY_WIFI_SSID, ssid);
    ret = system(shell_cmd);
    if (ret != 0) 
    {
        printf("modify ssid failed!n");
        return-1;
    }

    /* 修改WiFi密码 */
    memset(shell_cmd, 0, sizeof(shell_cmd));
    snprintf(shell_cmd, sizeof(shell_cmd), SHELL_CMD_MODIFY_WIFI_PSW, password);
    ret = system(shell_cmd);
    if (ret != 0) 
    {
        printf("modify psk failed!n");
        return-1;
    }

    return0;
}

int main(int argc, char *argv[])
{
    if (modify_wifi_config("LinuxZn", "88888888") == 0) 
    {
        printf("WiFi config modified successfully!n");
    } 
    else
    {
        printf("WiFi config modified failed!n");
    }

    return0;
}

运行结果:

相比原始写法,优化后的代码有以下改进:

五、注意

在实际项目中使用这种方式,有几点需要特别注意:

1. 操作前先备份

在修改配置文件之前,建议先保留一份默认配置文件(如示例中的 default_wpa_supplicant.conf),用于在修改出错时恢复。这在嵌入式设备上尤其重要——一旦配置损坏又没有备份,设备可能无法正常工作。

2. 注意命令注入风险

上面的代码中,ssid 和 password 通过 %s 拼接进 shell 命令。如果这些参数来自外部输入(如用户通过网页或串口输入),恶意用户可能构造特殊字符串来执行任意命令。例如输入 "; rm -rf / ; " 作为 ssid,后果不堪设想。

在实际产品中,务必对输入参数进行合法性校验,例如:

static int is_valid_input(const char *str)
{
    while (*str) 
    {
        if (*str == ';' || *str == '&' || *str == '|' ||
            *str == '`' || *str == '$' || *str == ''' || *str == '"') 
        {
            return 0;
        }
        str++;
    }
    return 1;
}

3. 分隔符冲突处理

如果要替换的内容中包含 / 字符(如文件路径),可以使用其他字符作为 sed 的分隔符,例如用 # 或 |

sed -i 's#/old/path#/new/path#g' config.txt

六、总结

这种方法不仅适用于 WiFi 配置,在嵌入式开发中还有很多场景可以复用:

修改网络配置:如 IP 地址、DNS、网关等(/etc/network/interfaces

调整串口参数:修改波特率、数据位等配置

更新服务器地址OTA 升级服务器、MQTT Broker 地址等

切换运行模式:修改应用启动参数或功能开关

只要配置文件是文本格式,都可以用 sed 来处理。

本文介绍了一种利用 sed 工具修改配置文件的实用方法。核心思路是:通过正则表达式匹配目标字段,用 sed 的替换功能一行命令完成修改,并可在 C 代码中通过 system() 调用实现自动化

这种方式的优点是简洁高效、无需引入额外的解析库,特别适合嵌入式 Linux 环境下对非标准配置文件的修改场景。

当然,如果项目中配置项较多、结构复杂,建议还是采用标准格式(如 JSON + cJSON),便于长期维护。选择合适的方案,才是工程实践的最优解。

如果觉得本文对你有帮助,欢迎点赞、在看、转发支持一波,我们下期见!

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

本公众号专注于嵌入式技术,包括但不限于C/C++、嵌入式、物联网、Linux等编程学习笔记,同时,公众号内包含大量的学习资源。欢迎关注,一同交流学习,共同进步!