xmlstarlet - 需要根据另一个属性的值有选择地替换属性值

时间:2014-01-18 01:16:02

标签: xmlstarlet

只是想知道是否有人可以帮助我。 我目前正在构建一个pfsense防火墙,它使用VPN连接来保护流量。 VPN提供商确实提供端口转发机制,但传入端口号每小时更改一次。我有一个脚本允许我发现新端口,但我需要一种脚本方式来修改防火墙中的端口转发设置以匹配。

控制此操作的防火墙配置文件的片段如下:

<?xml version="1.0"?>
<pfsense>
  <nat>
                <rule>
                        <source>
                                <any/>
                        </source>
                        <destination>
                                <any/>
                                <port>53400</port>
                        </destination>
                        <protocol>tcp/udp</protocol>
                        <target>192.168.0.15</target>
                        <local-port>53400</local-port>
                        <interface>opt2</interface>
                        <descr><![CDATA[Torrent]]></descr>
                        <associated-rule-id>nat_52d81d2dc904f5.77023355</associated-rule-id>
                        <created>
                                <time>1389894957</time>
                                <username>admin@192.168.0.20</username>
                        </created>
                        <updated>
                                <time>1389980696</time>
                                <username>admin@192.168.0.20</username>
                        </updated>
                </rule>
  </nat>

  <filter>
                <rule>
                        <id/>
                        <type>pass</type>
                        <interface>opt2</interface>
                        <ipprotocol>inet</ipprotocol>
                        <tag/>
                        <tagged/>
                        <max/>
                        <max-src-nodes/>
                        <max-src-conn/>
                        <max-src-states/>
                        <statetimeout/>
                        <statetype>keep state</statetype>
                        <os/>
                        <protocol>tcp/udp</protocol>
                        <source>
                                <any/>
                        </source>
                        <destination>
                                <address>192.168.0.15</address>
                                <port>53400</port>
                        </destination>
                        <log/>
                        <descr><![CDATA[NAT Torrent]]></descr>
                        <associated-rule-id>nat_52d81d2dc904f5.77023355</associated-rule-id>
                        <created>
                                <time>1389894957</time>
                                <username>NAT Port Forward</username>
                        </created>
                        <updated>
                                <time>1389899075</time>
                                <username>admin@192.168.0.20</username>
                        </updated>
               </rule>
  </filter>
</pfsense>

在上面的XML中,我们有两个部分,它们构成了pfsense的端口转发规则。 <nat>部分中包含的部分是前进端口。 <rule>中的部分是特定于接口的传入防火墙规则。必须修改两者才能使新端口转发设置生效。

我正在考虑使用xmlstarlet来修改配置文件,使用<descr>作为我的密钥来识别要更改的部分。

我知道您可以拥有以下数据:

<username><![CDATA[name]]></username>
<password><![CDATA[password]]></password>
<dbname><![CDATA[name]]></dbname>

并使用:

进行修改
xml ed -P -O -L \
  -u '//username/text()' -v 'something' \
  -u '//password/text()' -v 'somethingelse' \
  -u '//dbname/text()' -v 'somethingdifferent' file.xml

并且您可以拥有类似的内容:

<objects>
 <object>
    <name>Foo</name>
    <constant1>10</constant1>
    <constant2>20</constant2>
  </object>
  <object>
    <name>Bar</name>
    <constant1>15</constant1>
    <constant2>40</constant2>
  </object>
<objects>

并使用以下内容更新属性:

xmlstarlet ed -u '//object[name="Foo"]/const1' -v 18 sample.xml

但是,我正在努力合并这两个,因此我有一个与<descr>="Torrent"匹配的声明,然后更新相关的<port><local-port>属性。

非常感谢任何有关xmlstarlet命令的帮助。

1 个答案:

答案 0 :(得分:2)

xmlstarlet ed \
  -u '//rule[descr="Torrent"]/destination/port' -v 1111 \
  -u '//rule[descr="Torrent"]/local-port' -v 2222 \
  sample.xml