OpenWrt Shell脚本操作uci

UCI是OpenWrt系统中用于统一管理配置文件的组件,替代了传统的NVRAM配置。它提供了一种集中化的管理方式,简化了对应用程序配置的命令操作。文章介绍了UCI的依赖如libuci和libuci-lua,以及UCI配置文件的结构和shellapi接口的使用,包括config_load、config_get、config_foreach等,通过实例展示了如何通过shell脚本获取网络接口名。

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

1、什么是UCI

UCI是一个用C写的功能组件,为了集中化管理运行OpenWrt系统的设备的配置文件。UCI是在OpenWrt历史版本 White Russian 中存在的基于 NVRAM 的配置文件的替代版本和 其附带的标准配置文件程序的封装, 例如 /etc/network/interfaces, /etc/exports, /etc/dnsmasq.conf, /etc/samba/samba.conf 等。 

说白了,UCI就是为了统一应用程序的配置文件格式,方便统一用命令或者api接口去操作配置。当然应用程序原有配置保持不变,中间增加一层转换过程。

启动一个OpenWrt应用程序流程图如下:

                                     

 

2、UCI的依赖

  • libuci C语言实现的小型库

  • libuci-lua 一个为Lua写的UCI插件库,它在luci被使用

3、UCI附加包

包名描述
uci统一配置接口 (UCI) 的功能组件
libuci统一配都置接口 (UCI) 的C语言库
libuci-luaC语言库文件的LuaLua插件库, 例如 luci就用到了这个库

4、已安装的文件

路径/文件描述描述
/sbin/uci二进制文件/binaryuci 的可执行文件
/lib/config/uci.shshell脚本/Shell Script/sbin/uciShell脚本可用的封装
/lib/libuci.so符号链接/symlinklibuci.so.xxx 的符号链接
/lib/libuci.so.2011-01-19二进制文件binary

库文件

/usr/lib/lua/uci.so二进制文件/binarylua库文件

5、UCI配置文件

  • 配置路径

    /etc/config/

  • 配置文件内容(文件名class)

root@ZhouWu:/# cat  /etc/config/network 

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd78:ca3e:7361::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '10.10.18.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config interface 'wan'
        option device 'eth1'
        option proto 'dhcp'

config interface 'wan6'
        option device 'eth1'
        option proto 'dhcpv6'

config interface 'wwan'
        option device 'lan4'
        option proto 'dhcp'

  • uci命令操作实例

获取option值

获取list值

查看所有配置

修改option值

修改list内容(增加/删除)

6、shell api说明

  • shell api源码路径

    /lib/functions.sh

  • 主要接口列表

    config_load  

    config_get    

    config_set      

    config_foreach    

    config_list_foreach

    

7、config_get接口

  • 接口说明

用于获取option变量值

  • 接口参数

参数说明
$1  <variable>获取到的值存储变量
$2  <section>section名称
$3  <option>option名称
$4  <default>默认值
  • 接口实例

  config_get ifname_value "lan" ifname 

8、config_foreach接口

  • 接口说明

遍历指定类型的section,通过回调函数处理section

  • 接口参数

参数说明
$1  <callback>遍历callback
$2  <section type>section 类型
  • 接口实例

    handle_xxx()

    {

        local section="$1"

        #handle section

    }

    config_foreach  handle_xxx "interface"

9、实例:通过shell获取所有网卡接口名

可能通过以上接口文档,还不能直观的说明接口的用法,我写了一个实例通过shell脚本从uci网络配置中提取所有网络接口名,通过该实例可以学习config_load、config_get、config_foreach的用法,希望对大家有帮助。

  • OpenWrt系统网络配置

   配置文件路径

   /etc/config/network

   配置文件内容

config interface 'loopback'

option ifname 'lo'

option proto 'static'

option ipaddr '127.0.0.1'

option netmask '255.0.0.0'

config interface 'lan'

option type 'bridge'

option ifname 'eth0.1'

option proto 'static'

option ipaddr '192.168.166.1'

option netmask '255.255.255.0'

option ip6assign '60'

config device 'lan_dev'

option name 'eth0.1'

option macaddr '00:0c:43:76:20:d0'

config interface 'wan'

option ifname 'eth0.2'

option proto 'dhcp'

源代码

#!/bin/sh

. /lib/functions.sh

# 需要先load network配置,默认/etc/config/network

config_load network

# 每个section会调用一次

handle_intf()

{

local section="$1"

config_get ifname $section ifname

echo "interface=$ifname"

}

config_foreach  handle_intf "interface"

运行结果

interface=lo

interface=br-lan

interface=eth0.2

<think>嗯,用户提供的这段shell脚本有一个语法错误,提示在else部分有问题。我需要仔细检查代码的结构,找出哪里出错了。首先,用户提到的错误是“syntax error: unexpected 'else' (expecting 'then')”,这说明在某个if语句中,else出现的位置不对,可能是因为之前的if或then结构没有正确闭合。 看代码的话,首先注意到在判断metric和ltenable的if语句部分: if ["$metric" == "20" && "$ltenable" == "1" ] 这里可能存在空格问题。在bash中,测试命令[ ]内部的前后都需要有空格,而用户写的if ["$metric" == "20" ...],前面缺少了空格,应该是if [ "$metric" == "20" ... ]。这个错误会导致语法错误,进而导致整个if语句没有正确开始,后面的then可能没有被正确识别,从而导致else出现在不应该出现的位置。 另外,在if语句中的&&运算符可能需要使用-a或者用多个测试条件组合,不过在bash中,使用[[ ]]的话可以用&&,但如果是用[ ]的话,应该用-a。不过用户这里可能是在使用sh而不是bash,所以需要注意语法差异。不过更常见的是,用户可能忘记在[ ]周围的空格,导致语法错误。 所以,主要的修改点应该是修复if语句的空格问题。将if ["$metric" == "20" && "$ltenable" == "1" ]改为if [ "$metric" = "20" -a "$ltenable" = "1" ],或者如果使用bash的话,可以用[[ ]], 但需要考虑脚本的兼容性。或者保持原来的写法,但添加必要的空格,并且将&&替换为-a,因为[ ]内使用-a更可靠。 此外,还要检查其他可能的语法错误,比如是否所有if都有对应的then和fi闭合,是否有其他语法错误导致解析失败。例如,在用户提供的代码中,procd_close_instance后面是否正确闭合了所有的结构。 总结来说,主要问题在于if语句的空格和运算符使用不当,导致解析器在遇到else时没有正确识别前面的then,从而报错。修复这个if语句的结构应该解决语法错误。</think>该脚本的语法错误主要由if语句格式问题导致。修正后的代码如下: ```bash start_service() { . /lib/functions/network.sh local enable local metric local ltenable ltenable=$(uci get lte.config.enabled) metric=$(uci get network.lte.metric) # 修复条件判断的空格和逻辑运算符 if [ "$metric" = "20" -a "$ltenable" = "1" ] then enable=$(uci get network.lte.igmpproxy) else enable=$(uci get network.wan.igmpproxy) fi if [ "$enable" = "1" ] then config_load omcproxy config_foreach omcproxy_add_proxy proxy [ -n "$PROXIES" ] || return 0 procd_open_instance procd_set_param command $PROG [ -n "$OPTIONS" ] && procd_append_param command $OPTIONS procd_append_param command $PROXIES procd_set_param respawn procd_open_data json_add_array firewall config_foreach omcproxy_add_firewall_rules proxy json_close_array procd_close_data procd_close_instance echo 128 > /proc/sys/net/ipv4/igmp_max_memberships fi } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值