Perl для системного администрирования

       

Проверка ошибок в процессе генерирования файла узлов



Проверка ошибок в процессе генерирования файла узлов

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

Sdatafile ="./dataoase":

Srecorcsep = "- = -\;n:

# по одной записи за один раз

print "#\n\# host file - GENERATED BY $0\n# DO NOT EDIT BY HAND!\n#\n";
while (<DATA>) {

chomp; n удаляем разделитель записей

# разбиваем на key1,value1,... bingo, хэш записей
%record = split /:\s*|\n/m;

# проверка на неверные имена узлов

if ($record{name} =" /["-.a-zA-ZO-9]/) {
warn "!!!! $record{name} содержит недопустимые для имени узла символы

пропускаем...\п";
next;
}

# проверка на неверные псевдонимы

if ($record{aliases} =" /[~-.a-zA-ZO-9\s]/) {
warn "!!!! $record{name} содержит недопустимые для псевдонима символы,

пропускаем...\п";
next;
}



# проверка на пропущенные адреса
if (! $record{address» {

warn "!!!! $record{name} не имеет IP-адреса, пропускаем...\n";
next;
}

tt проверка на одинаковые адреса

if (defined $addrs{$record{address}>) {

warn "!!!! Дублируется IP-адрес: $record{name} &
$addrs{$record{address}}, пропускаем...\n";

next:
}
else {

$addrs{$record{address}} = $record{name};
}

print "$record{address}\t$record{name} $record{aliases}\n";
}
ClOse(DATA);

Улучшение полученного файла узлов

Позаимствуем из главы 9 «Журналы» процесс анализа выполняемого преобразования. Мы можем автоматически добавить полезные заголовки, комментарии и разделители к получаемым данным. Вот как выглядит результат преобразования той же самой базы данных:

#

К host file - GENERATED BY createhosts3 » DO NOT EDIT BY HAND!

Converted by David N. Blank-Edelman (dnb) on Sun Jun 7 00:43:24 1998

# number of hosts in the design department: 1.

ft number of hosts in the software department: 1.

# number of hosts in the IT department: 2.

# total number of hosts: 4
#

tt Owned by Cindy Coltrane (IT): west/143

if ($record->{aliases) =" /[~-.a-zA-ZO-9\s]/) {

warn "MM ". $record->{name} '.

содержит недопустимые для псевдонима символы, пропускаем,..\n";

next; }

tt проверка на пропущенные адреса if (!$record->{address}) {

warn "!!! ! ".$record->{name} .

не имеет IP-адреса, пропускаем,.Дл";

next; >

# проверка на совпадающие адреса

if (defined $addrs{$record->{address}}) {

warn "Ml! Дублируется IP-адрес:". $record->{name}.

" & ".$addrs{$record->{address}}.", пропускаем.. ";

next; 1 else {

$addrs{$record->{address}} = $record-><name}; }

$entries{$record->{name}} = $record; n добавляем это в хэш

tt хэшей } close(DATA);

It печатаем симпатичный заголовок

print "#\n\« host file - GENERATED BY $0\n# DO NOT EDIT BY HAND!\nff\n";

print "« Converted by $user on ".scalar(localtime). "\ntt\n";

# подсчитываем число записей для каждого отдела

Я и сообщаем об этом

foreach my Sentry (keys %entries){

Sdepts{Sentries{Sentry}->{department}}++; }

foreach my Sdept (keys %depts) {

print "n number of hosts in the

Sdept department: $depts{$dept},\n"; )

print "tt total number of hosts: ".

scalar(keys %entries). "\n#\n\n";

tt обходим в цикле все узлы, выводя комментарий и саму запись f

oreach my Sentry (keys %entries) {

print "tt Owned by ", $entries{$entry}->{owner}," (",

$entries{$entry>->{department},"): ",

Sentries{Sentry}->{building}."/",

Sentries{Sentry}->{room},"\n";

print $entries{$entry}->{address},"\t",

$entries{$entry}->{name}." ",

Sentries{Sentry}->{aliases},"\n\n"; }

Самое значительное отличие данного примера от предыдущего - это способ представления данных. Поскольку в предыдущем примере не было необходимости получать информацию из хэша после печати его значений, мы могли использовать единственный хэш. Но в этом случае мы решили прочитать данные из файла в более сложную структуру данных (хэш хэшей), чтобы проанализировать их перед тем как печатать.

Можно было сохранять отдельную хэш-таблицу для каждого поля (подобно тому, как это было сделано в примере needspace из главы 2 «Файловые системы»), но красота приведенного метода состоит в его поддерживаемости. Если затем понадобится добавить в базу данных поле serial_number, нам не придется менять используемый для анализа файла код, это поле само по себе появится. Недостаток же в том, что синтаксис Perl таков, что наш код выглядит более сложным, чем он есть на самом деле.

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

Чтобы построить большую структуру данных (хэш хэшей), достаточно связать каждый новый анонимный хэш с основной хэш-таблицей %entries и создать ключ со связанным с ним значением, являющимся ссылкой на этот только что заполненный анонимный хэш. Когда каждый хэш пройдет обработку, ключами %entries будут имена всех машин, а значениями - ссылки на хэш-таблицы, содержащие значения всех полей, связанных с этим именем (IP-адрес, номер кабинета и т. д.).

Вероятно, вам бы хотелось, чтобы вывод был отсортирован по IP-адресам? Никаких вопросов, просто добавьте процедуру сортировки, изменив:

foreach my Sentry (keys %entries) { на:

foreach my Sentry (sort byaddress keys %entries) { и добавьте:

sub byaddress {

@a = split(/\./,$entries{$a}->{address}):

@b = split(/\./.$e"tries{$b}-''{address)):

($a[0]<=>$b[OJ) ,!

($а[1]<=>$Ь[1!) ! i

($a[2]<=>$b[21) !|

($a[3]<=>$D[3]l;

Вот как будут выглядеть отсортированные данные:

И Owned by Cindy Coltranc (IT): west/143 192.168.1,3

tjendir ben bei.doooles

П Owned by David Davis (software): inai'i/909

192.168.1.11 shimmer snm siimr, sniiMiydoodies

n Owned by Ellen Monk (design): rain/1116

192.168.1.12 Sulawesi sula su-lee

# Owned by Alex Rollins (IT): rnain/1101 192.168.1.55

sander sandy micky mickydoo

Сделайте так, чтобы полученные данные вам нравились. Пусть Perl поддержит ваши профессиональные и эстетические стремления.



Содержание раздела