Mission 2
——UCI学习
Tools:
WinSCP
Reference:
《智能路由器开发指南》
Procedure:
1. 学习书本第四章主要内容。
4.1.1 文件语法 Openwrt的配置文件讲解
配置文件有配置节组成,配置节由多个“name/values”选项对组成。
每一个配置节都需要有一个类型标识,但不一定需要名称。语法如下:
Config [“”] #section
Option “” #option
在UCI的配置文件中通常包含一个或多个配置节,所谓的配置节是带有一个或多个选项的语句。如:
Config system
Option hostname OpenWrt
Option timezone UTC
Config timeserver ntp
List sever 0.openwrt.pool.ntp.org
List sever 1.openwrt.pool.ntp.org
List sever 2.openwrt.pool.ntp.org
List sever 3.openwrt.pool.ntp.org
Option enabled 1
Option enable_server 0
这里对应的是System/system的界面:
备注:NTP服务器:网络时间协议(Network Time Protocol),它是用来同步网络中各个计算机的时间的协议。
4.1.2 统一配置原理
Openwrt中很多第三方应用程序,大多数应用程序的软件包维护者已经制作了UCI兼容的配置文件,启动时由UCI配置文件转换为软件包的原始配置文件。这实在运行初始化脚本/etc/init.d中执行的。var目录为其内容在正常运行时不断变化的目录,因此将var目录创建为/tmp目录的一个链接。var目录中的配置文件,是由UCI配置文件生成覆盖的,是运行init.d中脚本进行配置文件转换的。Openwrt的大多数配置都基于UCI文件,若要在软件原始的配置文件调整设置,可以通过禁用UCI方法来实现。
在改变一个UCI的配置文件后,受影响的服务或可执行程序必须由init.d进行重启。如果只是直接启动可执行文件,没有通过init.d调用,将不会将一个UCI配置文件更新到特定程序相关的配置文件位置,则在/etc/config/的修改将不会对现有进程产生任何影响。
如:uci set network.lan.ipaddr=192.168.6.1
uci commit network
下一步通过运行一下命令使修改生效
/etc/init.d/network restart
4.1.3 UCI工具
UCI实用工具提供了修改和分析UCI文件的脚本编程开发接口。
注意,当时用UCI工具写入配置文件时,配置文件都是整个重写,并且不需要确认命令。这意味着在文件中,任何多余的注释行和空行都会被删除。如果你有UCI类型的配置文件,想保留自己的注释行和空行,那就不应该适用UCI命令行工具来编辑文件。
下面是UCI工具选项的含义和基本使用方法,以及一些如何实用这个非常便利的命令行借口工具的实例:
root@PandaKill:~# uci
Usage: uci [] []
Commands:
batch
export []
import []
changes []
commit []
add
add_list ..
=del_list ..
=show [[.[.
]]]get .[.
]set .[.
]=delete [.[[.
][=]]]rename .[.
]=revert [.[.
]]reorder .=
Options:
-c set the search path for config files (default: /etc/config)
-d set the delimiter for list values in uci show
-f use as input instead of stdin
-m when importing, merge data into an existing package
-n name unnamed sections on export (default)
-N don't name unnamed sections
-p add a search path for config change files
-P add a search path for config change files and use as default
-q quiet mode (don't print error messages)
-s force strict mode (stop on parser errors, default)
-S disable strict mode
-X do not use extended syntax on 'show'
例如设置值,如果你想更改系统局域网的网关地址,在配置文件/etc/config/network文件中:
root@PandaKill:/etc/config# uci set network.lan.ipaddr = 192.168.1.3
root@PandaKill:/etc/config# uci commit network
root@PandaKill:/etc/config# /etc/init.d/network restart
配置结束后,现在的配置文件已经更新并设置到网卡上了。如果是通过网络登录到OpenWrt上面的,就需要使用新的IP地址链接。
当有多个配置节类型相同或者为匿名配置节时,UCI使用数组数字引用他们。OpenWrt系统默认有3个网卡接口,可以通过network.@interface[0]来引用第一个,通过network.@interface[1]来引用第二个,通过network.@interface[2]来引用第三个。也可以使用负索引,例如network.@interface[-1],其中“-1”指的是最后一个,“-2”指的是倒数第二个,等等。这在最后增加新的规则列表时是非常方便的。以network配置文件为例:
# /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 ifname 'eth0.1'
option force_link '1'
option macaddr '22:76:93:2d:e3:84'
option type 'bridge'
option proto 'static'
option netmask '255.255.255.0'
option ip6assign '60'
option ipaddr '192.168.1.3'
config interface 'wan'
option ifname 'eth0.2'
option force_link '1'
option macaddr '22:76:93:2d:e3:85'
option proto 'dhcp'
如图所示:
示例:通过命令行创建配置文件。
命令:
root@PandaKill:~# touch /etc/config/hello
root@PandaKill:~# uci set hello.globe = system
root@PandaKill:~# uci set hello.globe=system
root@PandaKill:~# uci set hello.globe.agent=bjbook
root@PandaKill:~# uci set hello.globe.url='www.bjbook.net/openwrt'
root@PandaKill:~# uci set hello.globe.delay=100
root@PandaKill:~# uci commit
则通过WinSCP查看 /ect/config/hello文件
表示已经创建成功。
4.1.4 配置脚本
UCI模块提供了一个shell脚本(/lib/config/uci.sh)并封装了UCI命令行工具的功能,以使其他的软件包在将UCI配置文件转换为自己格式的配置文件时使用。如uci_load; uci_get; uci_get_state等函数名称,可以加在配置,从配置文件中获取值等。
在单独导入uci.sh时,uci_load函数并不能执行成功,因为uci_load函数引用了/lib/functions.sh的一些函数定义,因此在使用uci_load函数时需要导入function.sh的函数定义。functions.sh的主要原理是将配置文件中的配置选项设置到环境变量中,然后提供接口函数在环境变量中获取。其中设置到环境变量中调用了uci.sh中的uci_load函数。uci_load函数又调用functinos.sh定义的config(),option(),list()等函数,将配置导入环境变量中。在使用这些函数的时候,以点开头来将这些函数加载到执行空间中,注意点和执行文件中间有一个空格。例如:
. /lib/functions.sh //装载函数
通常的转换执行流程是首先通过调用config_load函数将UCI配置读入当前环境变量中。然后使用config_get等函数进行读取和转换配置。其中config_load函数默认从/etc/config 目录下读取配置,并设置到环境变量中。以config_get函数为例来说明执行流程。Config_get函数从环境变量中读取配置值并赋值给变量。这个函数至少要3个函数:1. 存储返回值的变量;2. 所要读取的配置节的名称;3. 所有读取的选项名称;4. 默认值,如果配置文件没有该选项则返回该默认值,是一个可选的参数。
以“uci_”开头的函数和以“config_”开头的函数功能大多相同。但是config从环境变量中读取,而uci从文件中获取。所以config只进行一次磁盘读取,而uci进行多次磁盘读取,这个速度差异在10倍左右。