Сценарий для изменения файла конфигурации XML

В Debian - и, вероятно, во многих других дистрибутивах - файл /etc/networks предназначен для совершенно другой цели (он даёт хорошо известные имена сетевым подсетям). Вот мой:

default         0.0.0.0
loopback        127.0.0.0
link-local      169.254.0.0

Возможно, вы хотели отредактировать /etc/network/interfaces?

auto eth0
iface eth0 inet static 
        address 10.1.0.180
        netmask 255.255.255.0
        gateway 10.1.0.255

Вы должны указать netmask, а также просто address. шлюз необязателен, но если вы хотите работать вне сети, он вам понадобится. Если у вас установлен пакет resolvconf, вы также можете использовать элементы dns-nameserver и dns-search.

Для удаления псевдонима, чтобы сеть могла переназначить IP-адреса, вам может понадобиться сделать это вручную:

ifconfig eth0:1 down
ifconfig eth0 down
service networking restart
3
16.02.2016, 04:05
2 ответа

Вы действительно не привели достаточно объемный пример XML, поэтому я немного предполагаю.

Я бы посоветовал использовать в этой работе хороший XML-парсер и perl.

Я настоятельно рекомендую вам НЕ использовать:

Потому что оба они хрупкие - они вроде работают в контролируемых обстоятельствах, но у вас есть неприятный хакерский код, который может таинственным образом сломается однажды.

Вместо этого - используйте синтаксический анализатор, поддерживающий xpath , который - в терминах XML - способ найти / выбрать нужный контент и изменить его.

Что-то вроде XML :: Twig - низкий барьер для входа. (XML :: LibXML также является хорошей альтернативой, но, скорее, более исчерпывающей).

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig; 

#parse the content - you probably want `parsefile` here instead. 
my $twig = XML::Twig -> new ( pretty_print => 'indented_a' ) -> parse ( \*DATA );

#select the node you want, alter it. 
$twig -> get_xpath('./ssh/enabled',0) -> set_text('false');

#print the output (to STDOUT) - you can print {$output_fh} $twig->sprint; instead
$twig -> print;


__DATA__
<xml>
  <www>
    <enabled>true</enabled>
    <ip>0.0.0.0</ip>
    <port>80</port>
  </www>
  <ssh>
    <enabled>true</enabled>
    <ip>0.0.0.0</ip>
    <port>2024</port>
  </ssh>
  <smtp>
    <enabled>true</enabled>
    <ip>0.0.0.0</ip>
    <port>25</port>
  </smtp>
</xml>

Примечание. get_xpath использует формат типа «структура каталогов». Он поддерживает как абсолютные пути в XML, так и относительные пути. Как описано выше, он будет работать с первым элементом, который соответствует этому пути (XML допускает несколько).

Однако вы можете сделать это в цикле foreach:

foreach my $thing ( $twig -> get_xpath ('//enabled') ) {
   $thing -> set_text('false'); 
}

, чтобы отключить все.

xpath довольно гибкий - это способ указания пути, элемента и атрибутов, и он идеально подходит для навигации по XML в виде регулярных выражений.

Итак, у вас есть такие конструкции, как // для рекурсивного поиска.

Или // узел [@ name = 'test'] , чтобы найти:

<node name="test">content</node>

Там есть удобный быстрый справочник , который дает простой способ узнать, как перемещаться по XML с помощью xpath.

2
27.01.2020, 21:22

Поскольку несколько узлов в вашем конфигурационном файле имеют дочерние узлы с тем же именем, я бы рекомендовал написать ваш скрипт так, чтобы он действительно понимал формат XML. Вот пример изменения двух элементов конфигурации с помощью Perl:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Simple;

my $config = 'config.xml';
my $xml = XMLin($config, KeepRoot => 1, ForceArray => 1,);

$xml->{config}->[0]->{ssh}->[0]->{enabled} = 'false';
$xml->{config}->[0]->{web}->[0]->{ip} = '127.0.0.1';

XMLout($xml, KeepRoot => 1, NoAttr => 1, OutputFile => $config,);

Вот мой входной файл config.xml:

<config>
  <ssh>
    <enabled>true</enabled>
    <ip>0.0.0.0</ip>
    <port>2024</port>
  </ssh>
  <web>
    <enabled>true</enabled>
    <ip>0.0.0.0</ip>
    <port>80</port>
  </web>
</config>

А вот выходной:

<config>
  <ssh>
    <enabled>false</enabled>
    <ip>0.0.0.0</ip>
    <port>2024</port>
  </ssh>
  <web>
    <enabled>true</enabled>
    <ip>127.0.0.1</ip>
    <port>80</port>
  </web>
</config>
1
27.01.2020, 21:22

Теги

Похожие вопросы