OpenWrt系统配置UCI

UCI简介

UCI 是 Openwrt 中为实现所有系统配置的一个统一接口,英文名 Unified Configuration Interface,即统一配置接口。每一个程序的配置文件都保存在/etc/config 目录,可以通过文本编辑器、uci(一个可执行程序)以及各种 API(Shell、Lua 和C)来修改这些配置文件。
UCI 配置文件由一个或多个 config 语句组成,每一个 config 语句伴随着一个或多个 option 语句。这样的由一个 config 语句以及伴随的几个 option 语句组成的段落就叫做一个 section。

例如:在/etc/config 目录下创建一个配置文件 example,其内容如下
root@OpenWrt:~# vi /etc/config/example

config example 'test'
		option name 'value'
		list collection 'first item'
		list collection 'second item'

config example 'test’中的 example 表示这个 section 的类型,'test’表示这个 section 的名称。
option name 'value’定义了一个“名称-值”对 name=value
list 定义了一个列表,表示一个名称有多个值,比如这里的 collection 就有 2 个值’first item’和’second item

#下面的例子都是正确的 UCI 语法
option example value
option 'example' value
option example "value"
option "example" 'value' 
option 'example' "value"
#下面的例子都是错误的 UCI 语法
option 'example" "value' (引号不对称)
option example some value with space (缺少引号,引起歧义,不知道哪几个单词相结合)

UCI 提供了一个命令行工具 uci,它可以对配置文件中的内容进行修改、添加、删除和读取。
直接输入uci可以查看uci的帮助信息和具体参数

在这里插入图片描述
UCI命令含义:

add         // 增加指定配置文件类型为 section-type 的匿名区段
add_list    // 对已存在的list选项增加字符串
commit      // 对给定的配置文件写入修改
export      // 导出一个机器可读格式的配置
import      // 以UCI语法导入配置文件
changes     // 列出配置文件分阶段修改的内容,即未使用 uci commit 提交的修改
show        // 显示指定的选项、配置节或配置文件
get         // 获取指定区段选项的值
set         // 设置指定配置节选项的值
delete      // 删除指定的配置节或选项
rename      // 对指定的选项或配置节重命名为指定的名字
revert      // 恢复指定的选项,配置节或配置文件

通过 uci 写配置文件后,整个配置会被重新写入配置文件,这意味着配置文件中任何无关行都会被删除,包括注释(#开头的内容)。因此如果你要保留自己写的注释,就只能通过文本编辑器修改配置文件。

常用功能配置文件含义:

/etc/config/dhcp        // dnsmasq软件包配置,包含dhcp和dns设置
/etc/config/dropbear    // SSH服务器选项
/etc/config/firewall    // 防火墙设置,包含网络地址转换、包过滤、端口转发等
/etc/config/network     // 网络配置,包含桥接、接口、路由配置
/etc/config/system      // 系统配置,包含主机名称、网络时间同步等
/etc/config/timeserver  // rdate的时间服务列表
/etc/config/luci        // 基本的LuCI配置
/etc/config/wireless    // 无限设置和wifi网络定义
/etc/config/uhttpd      // web服务器选项配置
/etc/config/upnpd       // miniupnpd UPnP服务设置
/etc/config/qos         // 网络服务质量的配置文件定义

openWrt系统的核心配置文件,都位于/etc/config/ 目录下。
例如修改网络ip:
uci set network.lan.ipaddr=192.168.x.x
uci commit network
通过运行以下命令修改生效:
/etc/init.d/network restart

通过 shell 脚本操作 UCI 配置

Openwrt 提供了一些 shell 脚本函数,这些函数使得操作 UCI 配置文件变得非常的高效。要使用这些 shell 函数,首先需
要加载/lib/functions.sh,然后实现 config_cb(), option_cb(), 和 list_cb()这些 shell 函数,当我们调用 Openwrt 提供的 shell
函数 config_load 来解析配置文件时,程序就会回调我们自己定义的 config_cb(), option_cb(), 和 list_cb()这些 shell 函数.

下面创建一个 shell 脚本 test.sh,其内容如下:

#!/bin/sh
. /lib/functions.sh

reset_cb

config_cb() {
		local type="$1"
		local name="$2"
		# commands to be run for every section
		if [ -n "$type" ];then
				echo "$name=$type"
		fi
}
option_cb() {
		local name="$1"
		local value="$2"
		# commands to be run for every option
		echo $name=$value
}
list_cb() {
		local name="$1"
		local value="$2"
		# commands to be run for every list item
		echo $name=$value
}

config_load $1

reset_cb 表示将 xxx_cb 这 3 个函数初始化为没有任何操作。config_load 首先从绝对路径文件名加载配置,如果失败再
从/etc/config 路径加载配置文件。xxx_cb 那 3 个函数必须在包含/lib/functions.sh 和调用 config_load 之间定义。

给 test.sh 添加可执行权限chmod +x test.sh,执行 test.sh

root@OpenWrt:/# ./test.sh dhcp
cfg02411c=dnsmasq
domainneeded=1
boguspriv=1
filterwin2k=0
localise_queries=1
rebind_protection=1
rebind_localhost=1
local=/lan/
domain=lan
expandhosts=1
nonegcache=0
authoritative=1
readethers=1
leasefile=/tmp/dhcp.leases
resolvfile=/tmp/resolv.conf.auto
lan=dhcp
interface=lan
start=100
limit=150
leasetime=12h
wan=dhcp
interface=wan
ignore=1
cfg06fe63=host
ip=192.168.10.104
mac=44:8A:5B:EC:49:27

可以看到,当 config_load 解析配置文件时,解析到 section 时,就会回调 config_cb,解析 option 时,就会回调 option_cb,
解析 list 时,就会回调 list_cb。我们可以在对应的函数里面添加自己的相关命令。

另一种方式是使用 config_foreach 针对每一个 section 调用一个指定的自定义的函数,看下面这个 shell 脚本 test.sh

#!/bin/sh
. /lib/functions.sh
reset_cb
handle_interface() {
		local config="$1"
		local custom="$2"
		# run commands for every interface section
		if [ "$config" = "$custom" ];then
				echo $custom
		fi
}
config_load $1
config_foreach handle_interface interface $2

这里定义了一个函数 handle_interface,然后以 handle_interface、interface 和$2 这 3 个参数调用 config_foreach。
config_foreach 会遍历以$1 指定的配置文件中的所有的 section,一旦其类型与参数 interface 相等时,则回调
handle_interface,在 config_foreach 函数内部,会以当前正在解析的 section 的 ID 和调用 config_foreach 时的第 3 个参
数作为调用 handle_interface 的参数。

root@OpenWrt:/# ./test.sh network wan
wan

这里以参数 network 和 wan 调用 test.sh,然后程序首先调用 config_load 加载配置文件 network,然后 config_foreach 在
配置文件 network 中搜寻类型为 interface 的 section,一旦找到就以当前 section 的 ID 和 wan 作为参数调用
handle_interface,在 handle_interface 函数中,得到 config=wan,custom=wan,最终打印出 wan。
使用 config_get 读取配置选项的值,该函数需要至少 3 个参数:

  • 一个存储返回值的变量
  • 要读取的 section 的 ID(如果是有名称的 section 就是其名称)
  • 要读取的 option 的名称

在 handle_interface 中使用 config_get 和 config_set 来读取和设置当前的 section。

#!/bin/sh
. /lib/functions.sh
reset_cb
handle_interface() {
		local config="$1"
		local custom="$2"
		# run commands for every interface section
		if [ "$config" = "$custom" ];then
				config_get prot $config proto
				echo $prot
		fi
}
config_load $1
config_foreach handle_interface interface $2
root@OpenWrt:/# ./test.sh network lan
static
root@OpenWrt:/# ./test.sh network wan
dhcp

如果明确知道 section 的名称,可以直接调用 config_get 读取配置选项的值。
config_set 用来设置配置选项的值,它需要 3 个参数:

  • section 的 ID(如果有名称就是其名称)
  • option 的名称  要设置的值

更多操作参考 Openwrt 官方文档http://wiki.openwrt.org/doc/devel/config-scripting

发布了73 篇原创文章 · 获赞 39 · 访问量 6808

猜你喜欢

转载自blog.csdn.net/hzlarm/article/details/102993291