生活服务
一文打尽UCI统一配置接口、UCI配置文件、UCI工具用法、UCI配置脚本、UCI API编程接口(Libubox库、UCI库)
2024-12-24 14:41  浏览:111

  • 接下来几篇文章首先讲述 UCI 配置及配置接口,接着讲述系统内核设置,最后还会讲述一些非 UCI 系统配置,这些配置通常不提供用户修改接口,但在系统运行时也是非常重要的。
  • MVC(Model-View-Control)模式是经典的Web开发编程模式,OpenWrt也采用该设 计模式。该设计模式为分层设计,模型层负责数据的持久化操作。OpenWrt 的模型层采用 统一配置接口(Unified Configuration Interface,UCI)。
  • 统一配置接口(Unified Configuration Interface,UCI,是OpenWrt成功的关键技 术之一,已经移植支持数千个软件。它采用纯文本文件来保存配置,并提供命令 行和 C 语言编程调用接口进行管理。
  • UCI的目的在于集中OpenWrt系统的配置。这样每一个开发人员只需学习一次即可, 减少了学习成本。这是 OpenWrt 成功的关键原因之一。它成功地应用于 OpenWrt 的 WhiteRussian 之后的系列版本。
  • UCI 可以看作OpenWrt系统中最重要系统设置的主要配置接口。通常情况下这些设置对设备的功能运转至关重要,例如网络接口的配置、DHCP 和防火墙设置等。
  • 配置节(section,是UCI配置的一个独立配置单元。UCI配置文件是由一个或多个配置节组成。配置节有一个配置类型属性,是以“config”开头,并且有一个可选名称。配置节包含一个或多个配置选项语句。
  • 格式配置文件由配置节(section)组成,配置节由多个“name/values”选项对(option)组成。

  • 注意事项
    • 每一个配置节(section)都需要有一个类型标识(type,但不一定需要名称(name)。
    • 每一个选项对(option)都有名称(name)和值(value,写在其所属于的配置节中。
    • UCI标识符和配置文件的名称只能包含字母 a~z、0~9 和_。例如连字符(-)是不允许的。
    • 选项的值可以包含任何字符,但需要将它们正确地加上引号。
    • 没有名称标识的配置节称为匿名配置节。
    • 类型(type)和选项(option)的含义均由应用程序来决定,类型一般用于应用程序决定如何处理配置节包含的配置选项。
    • 如果一个选项(type)是不存在的并且是必需的,那应用程序通常会触发一个异常或者记录一个异常的日志,然后程序退出。
    • 通常选项(option)在配置文件中都是使用空格或制表符缩进来标识,但这个并非是语法要求,仅仅是为了增加配置文件的可读性。
    • option和list用来提高配置文件的可读性,并且在语法上也要求使用关键字来表示配置选项的开始。

引号的使用

  • 通常不需要使用引号引上类型标识符(type)或值(value,引号只在封闭的值包含空格或制表符的情况下需要。它可以合法地使用双引号和单引号。
  • 下面是合法的UCI文件选项语法示例

  • 下面的例子是错误的UCI文件语法

演示案例

  • 下面是OpenWrt中的一个实际配置文件(/etc/config/system)。

  • “config system”语句定义了一个配置节的开始,配置类型为“system”,但没有名称。
  • 选项“option hostname OpenWrt”和“option timezone UTC”两行定义了“config system”配置节的两个简单配置。
  • “config timeserver ntp”语句定义了另外一个配置节的开始,类型为“timeserver”,名称为“ntp”。
  • 开始带有list关键字的选项,表示有多个值被定义,所有的语句有同一个选项名称“server”。在这个的例子中均为NTP服务器地址,组合为相同顺序的单链表来 处理。
  • OpenWrt有很多独立的第三方应用程序,大多数应用程序的软件包维护者已经制作了UCI兼容的配置文件,启动时由UCI配置文件转换为软件包的原始配置文件。这是在运行初始化脚本/etc/init.d/中执行的。
  • 因此,当开始执行一 个UCI兼容的守护进程初始化脚本,你应该意识到程序的原始配置文件被覆盖了。例如,在DNS代理服务器 dnsmasq进程启动的情况下,文件/var/etc/dnsmasq.conf 是从 UCI 配置文件/etc/config/dhcp生成并覆盖的,是运行/etc/init.d/dnsmasq脚本进行配置文件转换的。
  • 配置文件的存储因为应用程序的配置文件是启动时通过UCI转换生成,因此它不需要存储在非易失性存储器,通常存储在内存中而不是在闪存中,而var目录为其内容在正常运行时不断变化的目录,因此将var目录创建为/tmp目录的一个链接。
  • OpenWrt的大多数配置都基于UCI文件,如果你想在软件原始的配置文件调整设置,可以通过禁用UCI方法来实现。
  • UCI配置文件的修改OpenWrt系统的核心配置分成很多个文件,并且都位于/etc/config目录下。每个文件涉及系统配置的某一部分。你可以用一个文本编辑器修改,或用命令行实用程序UCI编辑配置文件。UCI的配置文件也可通过各种编程 API(如 shell、Lua和C等)来修改,这也是 Web 接口例如LuCI修改UCI文件的方式。
  • UCI配置文件修改后的重启无论是通过一个文本编辑器还是命令行工具修改配置文件,在改变一个 UCI 的配置文 件后,受影响的服务或可执行程序必须由 init.d 进行重启,这样更新 UCI 配置才会真正生 效软件特定的配置文件。
  • init.d对配置文件的转换许多程序是通过它们的初始化脚本与UCI配置兼容的。init.d将UCI配置转换为它们。init.d首先在该软件预期的位置生成这样的一个配置文件,它通过 重新启动可执行程序再次读入配置。注意:如果只是直接启动可执行文件,没有通过 init.d 调用,将不会将一个 UCI 配置文件更新到特定程序相应的配置文件位置,在/etc/config/的 修改将不会对现有进程有任何影响。
  • 所有的UCI配置文件均默认保存在“/etc/config”目录下
文 件 路 径含 义/etc/config/dhcpDnsmasq 软件包配置,包含 DHCP 和 DNS 设置/etc/config/dropbearSSH 服务器选项/etc/config/firewall防火墙配置,包含网络地址转换、包过滤和端口转发等/etc/config/network网络配置,包含桥接、接口和路由配置/etc/config/system系统设置,包含主机名称,网络时间同步等/etc/config/timeserverrdate 的时间服务列表/etc/config/luci基本的 LuCI 配置/etc/config/wireless无线设置和 Wi-Fi 网络定义/etc/config/uhttpdWeb 服务器选项配置/etc/config/upnpdminiupnpd UPnP 服务设置/etc/config/qos网络服务质量的配置文件定义

演示案例

  • 例如,在修改UCI配置文件时,如果你想将局域网网关IP地址从默认地址192.168.1.1修改为192.168.6.1,可以使用vi编辑器直接修改/etc/config/network。但是此处我们使用uci命令来修改。

  • 下一步通过运行以下命令使修改生效。
  • 在这种情况下,你需要使用新的IP地址来登录路由器设备。路由器常用功能配置文件。
  • 在开发调整配置时,可以直接使用vi编辑器修改UCI配置文件。但是UCI统一配置文件的目的就是所有 OpenWrt 配置可以通过统一接口读取和修改。对于开发人员而言,如 果使用 awk 和 grep 工具来解析将是非常低效的UCI实用工具提供了修改和分析UCI文件的脚本编程开发接口。

备注(重点

  • 当使用UCI工具写入配置文件时,配置文件都是整个重写并且不需要确认命令。这意味着在文件中任何多余的注释行和空行均会被删除。
  • 如果你有 UCI 类型的配置文件想保存自己的注释和空行,那就不应该使用UCI命令行工具来编辑文件。
  • 命令格式
  • options如下
    • -c <path>:set the search path for config files (default: /etc/config)
    • -d <str>:set the delimiter for list values in uci show
    • -f <file>:use <file> 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 <path>:add a search path for config change files
    • -P <path>: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'
  • command如下
命 令含 义add增加指定配置文件的类型为 section-type 的匿名区段。add_list对已存在的 list 选项增加字符串。commit对给定的配置文件写入修改,如果没有指定参数则将所有的配置文件写入文件系统。所 有的“uci set”“uci add”“uci rename”和“uci delete”命令将配置写入一个临时位置, 在运行“uci commit”时写入实际的存储位置。export导出一个机器可读格式的配置。它是作为操作配置文件的 shell 脚本而在内部使用,导 出配置内容时会在前面加“package”和文件名。import以 UCI 语法导入配置文件。changes列出配置文件分阶段修改的内容,即未使用“uci commit”提交的修改。如果没有指定 配置文件,则指所有的配置文件的修改部分。show显示指定的选项、配置节或配置文件。以精简的方式输出,即 key=value 的方式输出。get获取指定区段选项的值。set设置指定配置节选项的值,或者是增加一个配置节,类型设置为指定的值。delete删除指定的配置节或选项。rename对指定的选项或配置节重命名为指定的名字。revert恢复指定的选项,配置节或配置文件。

  • 有些运行中的状态值没有保存在/etc/config目录下,而是保存在/var/state下,这时可 以使用“-P”参数来查询当前状态值。

  • 网络配置的相关信息存放在/etc/config/network文件中。

  • 下面我们修改“lan”这个网络接口的IP地址(修改完在下面图中可以看到“lan”这个网络接口的IP地址为我们设置的值)。

  • 删除上面我们设置的IP地址。

  • 概念当有多个配置节类型相同或者为匿名配置节时,UCI使用数组数字引用它们。
  • 规则如下
    • ①例如:OpenWrt 系统默认有 3 个网卡接口,可以通过network.@interface[0]来引用第一个,通过network.@ interface[1]来引用第二个,通过network.@interface[2]来引用第三个。
    • ②也可以使用负索引, 例如network.@interface[−1],其中“−1”指的是最后一个,“−2”指的是倒数第二个,以此类推。

演示案例获取各个网卡名称

  • 我这个OpenWrt系统中有两个网卡

  • 当一个配置文件中的选项(option)为链表时,操作方法有所不同。

演示案例

  • 例如我们的/etc/config/system配置文件中就有“list”形式的链表选项。

  • 添加到链表中一个配置项

 

  • 删除链表中的一个配置项。

  • 删除链表中的所有配置项。
  • 下面我们创建一个helloRoute的配置。
  • 第一步先创建一个“hello”的配置文件

  • 第二步首先通过命令行创建配置文件。像上面的配置一样,如果你想增加一个配置节,大多数人都会想到使用“uci add”命令,但实际上“uci add”仅可以创建匿名配置节,不能完 成创建命名配置的目标,要使用“uci set”命令来完成。

  • 第三步设置配置节的3个选项。

 

  • 查看配置文件内容。

  • 脚本介绍UCI模块提供了一个 shell 脚本(/lib/config/uci.sh)并封装了UCI命令行工具的功能, 这样方便了其他软件包在将UCI配置文件转换为自己格式的配置文件时使用。
  • 主要的函数如下所示需要这些函数需要导入/lib/config/uci.sh。
函 数 名 称含 义uci_loadUCI文件中加载配置并设置到环境变量,可以通过env命令来查看。该命令需要和 functions.sh 中的定义共同使用。uci_get配置文件中获取值。至少需要一个参数,指明要获取的配置信息。例如获 取系统主机名称调用:uci_get system.@system[0].hostname。uci_get_state指定从/var/state中获取状态值。

uci_load函数的注意事项

  • 在单独导入uci.sh时,uci_load函数并不能执行成功,因为 uci_load函数引用了/lib/functions.sh的一些函数定义,因此在使用 uci_load 函数时需要先导入functions.sh的函数定义。
  • 调用uci_load函数将配置设置到环境变量中时,uci_load函数又调用了 functions.sh 定义的 config()、option()、list()等函数。
  • 脚本介绍functions.sh的主要原理是将配置文件中的配置选项设置到环境变量中,然后提供接口函数在环境变量中获取。
  • 调用uci_load函数将配置设置到环境变量中时,uci_load函数又调用了 functions.sh 定义的 config()、option()、list()等函数。
  • 在使用这些函数时,以点开头来将这些函数加载到执行空间中,注意点和执行文件中间有 一个空格。例如
  • 主要的函数如下所示
函 数 名 称含 义config供uci.sh调用,将配置节设置到环境变量中。option供uci.sh调用,将配置节中的选项设置到环境变量中。list供uci.sh调用,将配置节中的链表配置设置到环境变量中。config_load调用uci_load函数来从配置文件中读取配置选项,并设置到环境变量中。config_get从当前设置环境变量中获取配置值。config_get_bool从当前设置的环境变量中获取布尔值,并将它进行格式转换,如果为真,转换为1,否则转换为0。因为 UCI 的布尔值有多种类型均支持。on、true、enabled 和 1 表示真,off、false、disable 和0表示假。config_set将变量设置到环境变量中以便后续读取。注意:仅设置到环境变量中并没有设置到配置文件中。config_foreach对于未命名的配置进行遍历调用函数。共两个参数,第一个参数为回调函数,第 二个参数为配置节类型,这个函数适用于匿名配置节的转换处理。

配置文件选项的写入与读取

  • 我们知道functions.sh的主要原理是将配置文件中的配置选项设置到环境变量中,然后提供接口函数在环境变量中获取下面我们以config_load与config_get函数为例,介绍一下执行过程。
  • ①首先通过调用config_load函数将UCI配置读入当前环境变量中,默认从/etc/config目录下读取配置,并设置到环境变量中。
  • ②然后使用config_get等函数进行读取和转换配置。
  • ③我们以config_get函数为例来说明执行流程。config_get函数从环境变量中读取配置值并赋值给变量。该函数至少要3个参数。
    • 第1个参数为存储返回值的变量。
    • 第2个参数为所要读取的配置节的名称。
    • 第3个参数是所有读取的选项名称。
    • 第4个参数是为默认值,如果配置文件没有该选项则返回该默认值,是一个可选的参数。
  • “uci_”开头的函数是/lib/config/uci.sh脚本提供的,“config_”开头得函数是/lib/functions.sh脚本提供的。

相同点

  • 以“uci_”开头的函数和以“config_”开头的函数大多数功能完全相同。

不同点

  • “uci_get”等函数直接从文件中获取,而“config_get”函数从环境变量中读取。
  • 性能差异“config_get”函数使用“config_load”一次从配置文件中读取设置到环境变量中,以后均不再进行磁盘操作。而“uci_get”每次均从文件中读取。
  • 如果调用多次,两者性能差距就会显现,实际测试中两者相差10倍以上。因此在OpenWrt中大多使用以“config_”开头的“config_get”等函数进行配置文件转换。
  • 下图所示为OpenWrt 12.09的一个实际代码,在启动时,从配置文件中获取主机名称,并设置到内核中。

  • 上面我们介绍了UCI的脚本提供的命令接口,UCI还提供了C语言调用接口。下面在操作系统Ubuntu下来说明API的使用。
  • 首先准备UCI编程接口的使用环境:UCI软件依赖Libubox,因此首先编译Libubox,Libubox库编译好之后,就可以再去编译UCI库了。
  • 等到UCI库编译好之后,我们就可以在编写C语言程序时使用UCI库了。
  • Libubox库介绍Libubox是OpenWrt的一个必备的基础库,包含大小端转换、链表、MD5等实用工具基础库,采用Cmake来编译。

安装Cmake

  • 。Cmake是跨平台的产生Makefile的命令行工具,它应用于在脚本文件中配置工程
    • -D选项设置工程选项。
    • -i选项打开交互提示来进行设置。
  • CmakeLists.txtCmake是一个跨平台的编译系统生成工具。通过平台独立Cmake的listfiles文件来指定构建过程。这个文件在每一个源码目录树目录下均有一个,文件名为CmakeLists.txt。
  • 安装Cmake命令如下

编译、安装Libubox

  • 第一步下载Libubox的软件包。

  • 第二步使用cmake生成Makefile。
    • 命令最后的一个点,代表当前路径。
    • 设置了两个编译开关(BUILD_LUA:BOOL、BUILD_EXAMPLES:BOLL)为 OFF,这两个分别是lua和使用示例,我们不进行编译,因此把编译选项关闭。

  • 第三步 进行编译(make)、安装(make install)。
    • 在进行编译时,编译过程中会输出编译进度百分比。
    • 编译完成之后进行安装,安装到系统目录中,需要使用管理员权限并输入密码,因此会加上sudo命令。

  • 安装内容包含头文件和动态链接库文件。头文件默认安装在/usr/local/include/libubox目录下动态链接库libubox.so和 libubox.a安装在/usr/local/lib/目录下。

  • Libubox安装完成后就可以编译安装UCI软件了。

编译、安装UCI库

  • 第一步下载UCI软件包。

  • 第二步使用cmake生成Makefile。
  • 第三步编译、安装UCI。

  • UCI库的头文件安装在/usr/local/include目录下,动态链接库安装在/usr/local/lib/ libuci.so,可执行程序为/usr/local/bin/uci。

  • 第四步因为系统还不知道动态链接库已经安装,运行该命令会告诉系统重新加载动态链接库,这样UCI动态链接库就可以使用了。

  • UCI库编译好之后,就可以在C语言程序中使用UCI库了(-luci,例如下面使用gcc编译一个带有与UCI库的C程序。
  • UCI接口命名非常规范,统一以小写的uci开头并放在uci.h头文件中。
  • 大多数函数的第一个参数均为uci_context的指针变量。这个变量在程序初始化时调用uci_alloc_context函数分配空间并设置初始值。在程序执行结束时调用uci_free_context函数释放空间。
  • UCI接口有设置函数uci_set,但没有相应的获取函数uci_get,UCI使用uci_lookup_ptr来提供查询功,如果查到则通过获取ptr变量的值来获取配置的值。
函 数含 义uci_alloc_context分配UCI上下文环境对象。uci_free_context释放UCI上下文环境对象。uci_load解析UCI配置文件,并存储到UCI对象中。@name:配置文件名,相对于配置目录。@package:在这个变量中存储装载的配置包。uci_unload从UCI上下文环境对象中unload配置文件。uci_lookup_ptr分割字符串并查找。@ptr:查找的结果。@str:待查找的字符串,但 str 不能为常量, 因为将被修改赋值,在 ptr 变量内部会被使用到,因此 str 的寿命必须至少和 ptr 一样长。@extended 是否允许扩展查找。uci_set设置元素值,如果必要将创建一个元素。更新或创建的元素将存储在ptr-> last中。uci_delete删除一个元素,配置节或选项。uci_save保存一个package修改的delta。uci_commit提交更改package,提交将重新加载整个uci_package。uci_set_confdir修改UCI配置文件的存储位置,默认为/etc/config。
  • UCI API的使用案例,见文章:https://blog.csdn.net/qq_41453285/article/details/102545618。

  • 我是小董,V公众点击"笔记白嫖"解锁更多OpenWrt资料内容。
    以上就是本篇文章【一文打尽UCI统一配置接口、UCI配置文件、UCI工具用法、UCI配置脚本、UCI API编程接口(Libubox库、UCI库)】的全部内容了,欢迎阅览 ! 文章地址:http://ww.kub2b.com/tnews/266.html
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 企库往资讯移动站 http://ww.kub2b.com/mobile/ , 查看更多   
最新文章
腾讯围棋(野狐)手机版最新版中国象棋手机版「腾讯围棋(野狐)手机版最新版」
中国象棋竞技版最新版是有着很多经典的象棋残谱的经典益智游戏,在这里解锁自己感兴趣的棋谱,不管是是和电脑竞技还是真人pk,都
小米手机掉水里了应该怎么处理手机掉水里怎么处理「小米手机掉水里了应该怎么处理」
在日常生活中,我们难免会遇到一些突发情况,比如小米手机不慎掉入水中。面对这种情况,如果处理不当,可能会导致手机严重损坏。
有钱人“买爆”上海豪宅,有楼盘卖出200亿!去年多个“10万+”豪宅“日光”
本文来源:时代财经 作者:陈泽旋图源:图虫创意有钱人仍在楼市发挥他们的“钞能力”。近日,来自上海的中高端改善型项目海玥黄
华为WatchGT3可以遥控拍照吗?华为WatchGT3遥控拍照介绍华为手机驱动「华为WatchGT3可以遥控拍照吗?华为WatchGT3遥控拍照介绍」
近日有些朋友询问能否用华为Watch GT 3远程控制拍摄照片?以下是相关说明。(注:以上为简化版文本)华为WatchGT3支持遥控拍照,
谱写中印尼命运共同体新篇章
王鲁彤 中国和印度尼西亚是隔海相望的好邻居、命运与共的好伙伴,两国友谊源远流长。古代海上丝绸之路曾将双方紧密联系在一起,
东京股市继续上涨
  新华社东京4月18日电(记者钱铮)受医药和生物相关股普遍上涨拉动,日本东京股市18日继续上涨。日经225种股票平均价格指数收
如何有效格式化手机以清理存储空间和提升性能手机格式化是什么意思「如何有效格式化手机以清理存储空间和提升性能」
  在现代社会,手机已经成为我们生活中不可或缺的一部分。随着时间的推移,手机中的数据会逐渐增多,可能会导致设备运行缓慢,
如何快速关闭手机勿扰模式?详细步骤解析!手机勿扰模式在哪里「如何快速关闭手机勿扰模式?详细步骤解析!」
如何在Android手机上关闭勿扰模式 通过快捷设置关闭:用户可从屏幕顶部向下滑动以打开通知面板,接着找到“勿扰模式”图标(通常
microsd卡是什么卡手机sd卡是什么「microsd卡是什么卡」
  microsd卡是什么卡,很多人都有这样的疑问吧?下面就让我来为大家介绍一下吧!microsd卡是什么卡?  其实,MicroSD卡是一种
名茶汇聚的安徽,何以大而不强?
01为何名茶多,但名企少、名牌也少?说起安徽茶叶,大家第一印象是名优茶多,但这并不意味着龙头企业、知名品牌也多。中国十大名