网络条件允许的还是建议去https://openwrt.org/自己查看资料。
目录
UCI系统
缩写UCI代表“Unified Configuration Interface”(统一配置界面)的缩写,是集中的OpenWrt的服务配置的系统。
UCI是白俄文系列的OpenWrt中基于NVRAM的配置的继承者,并且是最重要的系统设置的主要配置用户界面。例如,例如主网络接口配置,无线设置,日志记录功能和远程访问配置。
此外,OpenWrt存储库中的许多软件包已与UCI系统兼容。
通过根据相应UCI文件中选择的设置简单地写入原始配置文件(由程序读取),即可使应用程序与UCI兼容。这是在中运行初始化脚本时完成的/etc/init.d/
。有关更多信息,请参见初始化脚本(Init scripts)。因此,在使用兼容UCI的初始化脚本启动守护程序时,应注意该程序的原始配置文件将被覆盖。例如,在Samba / CIFS的情况下,文件/etc/samba/smb.conf
被覆盖从UCI配置文件UCI设置/etc/config/samba
运行时/etc/init.d/samba start
。此外,应用程序的配置文件通常存储在RAM中而不是闪存中,因为它不需要存储在非易失性存储器中,并且每次更改后都会基于UCI文件进行重写。万一您想调整无法通过UCI获得的原始配置文件中的设置,可以使用一些禁用UCI的方法,例如,在cifs.server中,您可以看到如何为samba禁用UCI。
对于那些不兼容UCI的程序,有一些您可能希望使用的非UCI配置文件的便捷列表。请注意,对于大多数第三方程序,您应该查阅程序自己的文档。
共同原则
OpenWrt的中央配置被分成/etc/config/
目录中的几个文件。每个文件都与它所配置的系统部分有关。您可以使用文本编辑器编辑配置文件,也可以使用命令行实用程序对其进行修改uci
。还可以通过各种编程API(例如Shell,Lua和C)修改UCI配置文件,这也是Web接口(例如LuCI)如何更改UCI文件的方式。
更改UCI配置文件时,无论是通过文本编辑器还是通过命令行,都必须通过init.d调用(init.d call)(重新启动)(或在某些情况下只需重新加载)受影响的服务或可执行文件,以便更新的UCI配置将应用于它们。通过使init.d脚本写入其特定于软件的标准配置文件,可以使许多程序与UCI兼容。首先,init.d脚本会将此类配置文件正确写入软件的预期位置,然后通过重新启动可执行文件再次读取该配置文件。请注意,仅直接(重新)启动可执行文件而不进行init.d调用不会导致UCI更新以将UCI配置委托给程序的预期配置文件。文件中的更改/etc/config/
然后不起作用。
作为修改UCI配置的示例,假设您要将设备的IP地址从默认值更改192.168.1.1
为192.168.2.1
。为此,请使用任何文本编辑器(例如vi)更改行
option ipaddr 192.168.1.1
在文件/etc/config/network
中:
option ipaddr 192.168.2.1
接下来,通过运行来提交设置
/etc/init.d/network restart
在这种情况下,请记住您必须使用SSH重新登录,因为现在可以使用其新IP地址访问该设备!
配置文件
文件语法
UCI配置文件通常包含一个或多个config
语句,即所谓的节,其中包含一个或多个用于定义实际值的选项语句。
A #
以通常的方式开始评论。具体来说,如果一行包含#
字符串文字的外部内容,则该行及其后面的所有字符都将被视为注释并被忽略。
以下是一个简单配置文件的示例(另请参见uci_dataobject_model):
package 'example' config 'example' 'test' option 'string' 'some value' option 'boolean' '1' list 'collection' 'first item' list 'collection' 'second item'
-
该
config 'example' 'test
“语句定义与类型一节的开始example
和名称test
。也可能有所谓的匿名部分,仅具有类型,但没有名称标识符。类型对于处理程序决定如何处理所附选项非常重要。
-
的
option 'string' 'some value
“和option 'boolean' '1
”线的截面内限定简单的值。请注意,文本选项和布尔选项之间在语法上没有区别。按照约定,布尔选项可以具有值'0','no','off','false'或'disabled'之一,以指定false值或'1','yes','on','true '或'启用'以指定一个真值。
-
在以
list
关键字开头的行中,定义了具有多个值的选项。在我们的示例中,所有list
共享相同名称的语句collection
将被组合为一个值列表,其配置顺序与配置文件中的顺序相同。
-
option
和list
语句的缩进是为了提高配置文件的可读性的约定,但是在语法上不是必需的。
-
如果缺少选项并且不需要,则使用默认值。如果不存在并且是必需的,则可能会触发应用程序中的错误或其他不良行为。
-
禁用没有
enabled
禁用选项的配置节的一种方法是将配置节标识符(在这种情况下example
为类型)重命名为使用这些值的进程无法识别的值。通常,一个disabled_identifier
as config section type / identifier就足够了。
通常,您不需要将标识符或值括在引号中。仅当包含的值包含空格或制表符时,才需要使用引号。在键入配置选项时,使用双引号而不是单引号也是合法的。
以下所有示例都是有效的UCI语法:
option example value option example "value" option 'example' value option 'example' "value" option "example" 'value'
相反,以下示例不是有效的UCI语法:
# missing quotes around the value option example v_a l u-e # unbalanced quotes option 'example" "value'
重要的是要知道,UCI标识符和配置文件名可能只包含字符是非常重要的a-z
,0-9
和_
。例如,不允许使用连字符(-
)。选项值可以包含任何字符(只要正确加引号即可)。
编辑器插件
语法高亮显示和在vim中(略)更多:vim-uci-与sshfs(需要openssh-sftp-server)一起很好地工作。
命令行实用程序
为了调整设置,通常可以直接更改UCI配置文件。但是,出于脚本目的,还可以使用uci
命令行实用程序读取和更改所有UCI配置。对于需要自动解析UCI配置的开发人员,因此使用awk
和grep
解析OpenWrt的配置文件是多余的,不明智的且效率低下的。该uci
实用程序提供了有关修改和解析UCI的所有功能。
以下是用法,以及一些有关如何使用此强大实用程序的有用示例。
当使用uci
写配置文件,该文件总是重写全部并省略不识别的命令。这意味着将删除文件中的所有多余行,例如注释。如果您拥有自己编辑的UCI配置文件,并且想要保留自己的注释和空白行,则不应使用命令行实用程序,而应正常编辑文件。请注意,首次安装应用程序时,某些文件(例如uHTTPd配置文件)已经包含许多注释。另外,请注意,某些应用程序(例如LuCI)也使用该uci
实用程序,因此可能会重写UCI配置文件。
当多个规则彼此相邻时,UCI支持它们的类似数组的引用。如果在中定义了8台NTP服务器/etc/config/system
,UCI将允许您参考system.@timeserver[0]
第一个或system.@timeserver[7]
最后一个服务器的部分。您还可以使用负索引,例如system.@timeserver[-1]
。“ -1”表示最后一个,“-2”表示倒数第二,依此类推。将新规则附加到列表末尾时,这非常方便。请参阅下面的示例。
用法
# uci Usage: uci [<options>] <command> [<arguments>]
Commands:
batch
export [<config>]
import [<config>]
changes [<config>]
commit [<config>]
add <config> <section-type>
add_list <config>.<section>.<option>=<string>
del_list <config>.<section>.<option>=<string>
show [<config>[.<section>[.<option>]]]
get <config>.<section>[.<option>]
set <config>.<section>[.<option>]=<value>
delete <config>[.<section[.<option>]]
rename <config>.<section>[.<option>]=<name>
revert <config>[.<section>[.<option>]]
reorder <config>.<section>=<position>
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 |
目标 | 描述 |
---|---|---|
commit |
[<config>] |
将给定配置文件的更改(如果未给出任何更改,则将所有配置文件)写入文件系统。所有“ uci集”,“ uci添加”,“ uci重命名”和“ uci删除”命令都暂存到一个临时位置,并通过“ uci commit”一次写入闪存。使用文本编辑器编辑配置文件后,不需要此操作,但是对于脚本,GUI和直接与UCI文件一起使用的其他程序,则不需要这样做。 |
batch |
-- | 执行多行UCI脚本,该脚本通常包装在here文档语法中。 |
export |
[<config>] |
以机器可读格式导出配置。它在内部用于将配置文件评估为Shell脚本。 |
import |
[<config>] |
以UCI语法导入配置文件。 |
changes |
[<config>] |
列出对给定配置文件或所有给定配置文件的暂存更改。 |
add |
<config> <section-type> |
将匿名类型的部分添加section-type 到给定的配置中。 |
add_list |
<config>.<section>.<option>=<string> |
将给定的字符串添加到现有列表选项。 |
del_list |
<config>.<section>.<option>=<string> |
从现有列表选项中删除给定的字符串。 |
show |
[<config>[.<section>[.<option>]]] |
以压缩符号显示给定的选项,部分或配置。 |
get |
<config>.<section>[.<option>] |
获取给定选项的值或给定节的类型。 |
set |
<config>.<section>[.<option>]=<value> |
设置给定选项的值,或添加类型设置为给定值的新部分。 |
delete |
<config>[.<section[.<option>]] |
删除给定的部分或选项。 |
rename |
<config>.<section>[.<option>]=<name> |
将给定的选项或部分重命名为给定的名称。 |
revert |
<config>[.<section>[.<option>]] |
还原给定的选项,节或配置文件。 |
reorder |
<config>.<section>=<position> |
将节移到另一个位置。 |
UCI数据/对象模型
元素
UCI模型中的元素是:
-
config :主要配置组,如 网络 , 系统 , 防火墙 。每个配置组在 / etc / config中都有其自己的文件
-
sections :配置分为几个部分。节可以 命名 或 不命名 。
-
类型 :一个节可以有一个类型。例如,在网络配置中,我们通常具有“接口”类型的4个部分。这些部分是“ lan”,“ wan”,“ loopback”和“ wan6”
-
选项 :每个部分都有一些选项,您可以在其中设置配置值
-
值 :期权的价值
节命名
在命名方面,各节应有一些额外的解释。节可以命名或不命名。未命名的部分将获得自动生成的ID / CFGID(autogenerated ID/CFGID)(例如“ cfg073777”),并显示一个匿名名称(anonymous-name)(例如“ @switch [0]”)
匿名名称 示例:
# uci show network ... network.@switch[0]=switch network.@switch[0].name='switch0' network.@switch[0].reset='1' network.@switch[0].enable_vlan='1' ...
自动生成的ID / CFGID 示例:
# uci show network.@switch[0] network.cfg073777=switch network.cfg073777.name='switch0' network.cfg073777.reset='1' network.cfg073777.enable_vlan='1'
不同的介绍
相同的配置部分可以以不同的方式呈现:
-
人性化:如配置文件中所示或使用命令“ uci export <config>”显示
-
可编程的:如命令“ uci show <config>”所示
不同的模型展示 | ||
---|---|---|
人性化的命名部分(“ uci出口网络”) | 人性化,未命名的部分(“ uci出口网络”) | |
![]() |
![]() |
|
可编程的命名部分(“ uci show network.wan”) | 可编程的,未命名的部分,匿名名称(“ uci show network”) | 可编程的未命名部分,CFGID(“ uci show network。@ switch [0]”) |
![]() |
![]() |
![]() |
例子
设定值
如果要将uHTTPd Web服务器的侦听端口从80更改为8080,请在/etc/config/uhttpd
以下位置更改配置:
uci set uhttpd.main.listen_http='8080' uci commit uhttpd /etc/init.d/uhttpd restart
完成,现在配置文件已更新,uHTTPd侦听端口8080。
导出整个配置
uci export SUBSYSTEM_NAME
可用的子系统包括:默认值,dnsmasq,dropbear,防火墙,fstab,net,qos,samba,system,wireless。
显示子系统的当前配置
uci show SUBSYSTEM_NAME
这里是一个例子:
# uci show system system.@system[0]=system system.@system[0].hostname='OpenWrt' system.@system[0].timezone='UTC' system.ntp=timeserver system.ntp.server='0.openwrt.pool.ntp.org' '1.openwrt.pool.ntp.org' '2.openwrt.pool.ntp.org' '3.openwrt.pool.ntp.org' system.ntp.enabled='1' system.ntp.enable_server='0'
仅显示选项的值
uci get httpd.@httpd[0].port
将条目追加到列表
uci add_list system.ntp.server = '0.de.pool.ntp.org'
完全替换列表
uci delete system.ntp.server uci add_list system.ntp.server='0.de.pool.ntp.org' uci add_list system.ntp.server='1.de.pool.ntp.org' uci add_list system.ntp.server='2.de.pool.ntp.org'
在子系统配置中添加新部分
uci add SUBSYSTEM_NAME SECTION_NAME
它将在名为SUBSYSTEM_NAME的子系统内生成一个名为SECTION_NAME的新节。之后,您可以像往常一样向此部分添加密钥。它将打印一个字母数字代码,您可以将其用作“部分”以进一步向其添加密钥。
请参阅以下示例:
uci add firewall rule uci set firewall.@rule[-1].src='wan'
显示尚未保存的修改值
uci changes
保存单个子系统的修改值
uci commit SUBSYSTEM_NAME reload_config
保存所有修改的值
uci commit reload_config
通过简单的复制粘贴生成完整的uci部分
当您添加新的部分(见上文)时,此代码块将捕获uci打印的代码,并在您要在其后添加的所有新键中重复使用。这将使非常有趣的键入或复制粘贴作业自动化。您也可以在脚本中执行此操作。
通用版本:
rule_name=$(uci add <config> <section-type>) uci batch << EOF set <config>.$rule_name.<option1>='value' set <config>.$rule_name.<option2>='value' set <config>.$rule_name.<option3>='value' ... EOF uci commit
一个工作示例:
rule_name=$(uci add firewall rule) uci batch << EOF set firewall.$rule_name.enabled='1' set firewall.$rule_name.target='ACCEPT' set firewall.$rule_name.src='wan' set firewall.$rule_name.proto='tcp udp' set firewall.$rule_name.dest_port='111' set firewall.$rule_name.name='NFS_share' EOF uci commit
创建给定类型的新命名节
创建一个新的blah类型的_anonymous_部分:
uci add blah
例:
# uci import playapp < /dev/null # uci show playapp # uci add playapp blah # uci commit # uci show playapp playapp.@blah[0]=blah
例如,如果您实际上想要该类型的命名节,
config blah this_name option xxx yyy config blah other_name option xxx zzz
然后uci add
不能使用,而是使用以下语法:
# uci import playapp < /dev/null # uci set playapp.myname=mysectiontype # uci set playapp.othername=mysectiontype # uci commit # uci show playapp playapp.myname=mysectiontype playapp.othername=mysectiontype
UCI路径
考虑以下示例配置文件:
config bar 'first' option name 'Mr. First' config bar option name 'Mr. Second' config bar 'third' option name 'Mr. Third'
那么下面的路径在每个组中是相等的:
# Mr. First uci get foo.@bar[0].name uci get foo.@bar[-0].name uci get foo.@bar[-3].name uci get foo.first.name # Mr. Second uci get foo.@bar[1].name uci get foo.@bar[-2].name # uci get foo.second.name won't work; label 'second' undefined # Mr. Third uci get foo.@bar[2].name uci get foo.@bar[-1].name uci get foo.third.name
如果显示它,您将得到:
# uci show foo foo.first=bar foo.first.name='Mr. First' foo.@bar[0]=bar foo.@bar[0].name='Mr. Second' foo.third=bar foo.third.name='Mr. Third'
但是,如果您使用uci show foo.@bar[0]
,则会看到:
# uci show foo.@bar[0] foo.first=bar foo.first.name='Mr. First'
添加防火墙规则
这是添加防火墙规则以转发TCP SSH端口以及uci所使用的负(-1)语法的一个很好的示例。
uci add firewall rule uci set firewall.@rule[-1].src='wan' uci set firewall.@rule[-1].target='ACCEPT' uci set firewall.@rule[-1].proto='tcp' uci set firewall.@rule[-1].dest_port='22' uci commit firewall /etc/init.d/firewall restart
获取WAN接口
# Runtime configuration . /lib/functions/network.sh network_flush_cache network_find_wan NET_IF network_find_wan6 NET_IF6 network_get_device NET_DEV "${NET_IF}" network_get_device NET_DEV6 "${NET_IF6}" echo "${NET_DEV}" echo "${NET_DEV6}" # Persistent configuration uci get network.wan.ifname uci get network.wan6.ifname
获取WAN IP地址
# Runtime configuration . /lib/functions/network.sh network_flush_cache network_find_wan NET_IF network_find_wan6 NET_IF6 network_get_ipaddr NET_ADDR "${NET_IF}" network_get_ipaddr6 NET_ADDR6 "${NET_IF6}" echo "${NET_ADDR}" echo "${NET_ADDR6}" # Persistent static configuration uci get network.wan.ipaddr uci get network.wan6.ip6addr
获取WAN网关
# Runtime configuration . /lib/functions/network.sh network_flush_cache network_find_wan NET_IF network_find_wan6 NET_IF6 network_get_gateway NET_GW "${NET_IF}" network_get_gateway6 NET_GW6 "${NET_IF6}" echo "${NET_GW}" echo "${NET_GW6}" # Persistent static configuration uci get network.wan.gateway uci get network.wan6.ip6gw
获取SSID
uci get wireless.@wifi-iface[0].ssid
UCI默认值
要在设备首次启动时设置一些系统默认值,请在文件夹中创建一个脚本/etc/uci-defaults/
。
该文件夹中的所有脚本均由脚本自动执行,/etc/init.d/boot
并且如果它们随后以代码0 删除而退出(未以代码0退出的脚本不会被删除,并且在下次启动期间将被重新执行,直到它们也成功退出)。
在实时路由器中,您可以在中看到现有的uci-defaults脚本/rom/etc/uci-defaults
,因为/etc/uci-defaults
它本身通常是空的(在所有脚本运行正常并被删除之后)。
这是在首次启动时更改默认IP的简单示例。
#!/bin/sh uci set network.lan.ipaddr='192.168.178.1' uci commit network exit 0
这是更改默认SSID并在首次启动时打开WiFi的简单示例。
#!/bin/sh uci set wireless.@wifi-device[0].disabled='0' uci set wireless.@wifi-iface[0].ssid='OpenWrt0815' uci commit wireless exit 0
在固件中包括uci-defaults脚本的最简单方法可能是作为自定义文件。请参阅Buildroot-自定义文件或Image Generator-自定义文件
将UCI移植到其他Linux发行版
损坏的配置
如果您在中手动编辑了配置/etc/config/
,则其中某些配置可能由于拼写错误而损坏。
# uci show fstab uci: Parse error (invalid command) at line 20, byte 0
运行以下命令以查找损坏的配置。
for CONF in /etc/config/* ; do uci show "${CONF##*/}" > /dev/null || echo "${CONF}"; done