uci - 如何恢复所有未暂存的更改

uci - how to revert all unstaged changes

uci 文档说:

All "uci set", "uci add", "uci rename" and "uci delete" commands are staged into a temporary location and written to flash at once with "uci commit".

如果我做对了,您首先 运行 一些命令,如上面提到的那些,然后将更改写入您 运行 uci commit 的配置文件。例如,假设我做了以下更改...

root@OpenWrt:~# uci changes
network.vlan15.ifname='eth1.15'
network.vlan15.type='bridge'
network.vlan15.proto='static'
network.vlan15.netmask='255.255.255.0'
network.vlan15.ipaddr='192.168.10.0'

...但我不想继续提交它们。有没有一种简单的方法可以还原所有阶段性更改并避免一项一项地进行?

我没有找到 uci 命令来还原所有未提交的更改,但您可以使用一些 shell 脚本来解析 uci changes 命令的输出以实现所需结果。这是一个示例脚本:

#!/bin/ash

# uci-revert-all.sh
# Revert all uncommitted uci changes

# Iterate over changed settings
# Each line has the form of an equation, e.g. parameter=value
for setting in $(uci changes); do

    # Extract parameter from equation
    parameter=$(echo ${setting} | grep -o '^\(\w\|[._-]\)\+')

    # Display a status message
    echo "Reverting: ${parameter}"

    # Revert the setting for the given parameter
    uci revert "${parameter}"
done

更简单的替代方法可能是使用 uci revert <config> 语法,例如:

#!/bin/ash

# uci-revert-all.sh
# Revert all uncommitted uci changes

for config in /etc/config/*; do
    uci revert $(basename ${config})
done

我在路由器 运行 LEDE 4.

上这两种方法都很好用

这应该可以通过以下命令实现:

root@firlefanz:~# rm -rf /tmp/.uci/

有一个命令可以恢复所有暂存的更改

revert  <config>[.<section>[.<option>]]     Revert the given option, section or configuration file.

所以,在你的情况下,应该是

uci revert network.vlan15

https://openwrt.org/docs/guide-user/base-system/uci

这条单线应该可以解决问题:

uci changes | sed -rn 's%^[+-]?([^=+-]*)([+-]?=.*|)$%%' | xargs -n 1 uci revert

tl;dr sed 命令从暂存更改中提取选项名称。 xargs 命令对每个提取的选项执行恢复命令。

现在让我们深入探讨一下:

uci changes 打印准备好的更改,然后将其通过管道传输到 sed 命令。

sed 选项 -r 启用扩展的正则表达式并且 -n 抑制模式匹配的自动打印。

sed 命令 s 用于搜索和替换,% 用作搜索和替换项的分隔符。

uci 变化行有不同的格式。

删除的配置选项以 - 为前缀。 添加的配置选项以 + 为前缀 更改的选项没有前缀。

要匹配前缀 [+-]?。问号表示,方括号中的字符之一可以匹配可选。

选项名称将与模式 [^=+-]* 匹配。只要字符不是 =+- 之一,此正则表达式就具有任意数量的字符的含义。 它在圆括号内以将其标记为组以便稍后重用。

下一个模式([+-]?=.*|)也是一个模式组。管道吐出两个不同的组。 第二部分很简单,完全没有个性。当删除 uci 选项时会发生这种情况。 第一部分表示字符 = 可以选择使用 +- 作为前缀。 =后面可以是一个或多个字符,用.*表示。 =<value> 发生在添加的配置上。如果选项是列表,-+ 的前缀表示从列表中删除或添加到列表中的值。

在替换模式中,整行被其引用 </code> 的第一组替换。换句话说:只打印选项名称。</p> <p>然后将所有选项名称发送到 xargs。使用选项 <code>-n 1 xargs 对 sed 发送的每个 option_name 执行 uci revert <option_name>

这是 uci changes 输出的不同格式的一些示例:

-a
+b='create new option with this value'
c='change an existing option to this value'
d+='appended to list'
e-='removed from list'

提取的选项名称如下:

a
b
c
d
e

xargs -n 1 将执行以下命令:

uci revert a
uci revert b
uci revert c
uci revert d
uci revert e

这就是单线的全部魔力。

这是另一个简短的 one-liner 来还原 ALL 未暂存的更改(根据问题):

for i in /etc/config/* ; do uci revert ${i##*/} ; done

(仅供参考,这使用 posix parameter expansion 的“删除最大前缀模式”。)