Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 [ 70 ] 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

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

$naraes = "А40 А А40 s";

$names length = length(pack($naraes)); # вероятно, 83

Базы данных с записями переменной длины (текстовые)

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

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

Perl поддерживает редактирование такого типа в строчно-ориентирован-ных базах данных методом редактирования на месте. Редактирование на месте - это модификация способа, посредством которого операция "ромб" (О) считывает данные из списка файлов, указанного в командной строке. Чаще всего этот режим редактирования включается путем установки аргумента командной строки -i, но его можно запустить и прямо из программы, как показано в приведенных ниже примерах.

Чтобы запустить режим редактирования на месте, присвойте значение скалярной переменной $ i. Оно играет важную роль и будет сейчас рассмотрено.

Когда используется конструкция о и переменная $i имеет значение, отличное от undef, к списку неявных действий, которые выполняет операция "ромб", добавляются шаги, отмеченные в приведенном ниже коде комментарием ## inplace ##:

$ARGV = shift @ARGV; open (ARGV, "<$ARGV") ;

rename($ARGV,"$ARGV$-I"); ## INPLACE ## unlink($ARGV); ## INPLACE ##



open(ARGVOUT,">$ARGV"); ## INPLACE ##

select(RRGVOUT); «« INPLACE ««

В результате в операции "ромб" при чтении используется старый файл, а запись в дескриптор файла по умолчанию осуществляется в новую копию этого файла. Старый файл остается в резервной копии, суффикс имени файла которой равен значению переменной $1. (При этом биты прав доступа копируются из старого файла в новый.) Эти щаги повторяются каждый раз, когда новый файл берется из массива SARGV.

Типичные значения переменной $"1 - .Ьак или ~, т.е. резервные файлы создаются почти так же, как это делается в текстовом редакторе. Странное и полезное значение $1 - пустая строка (""), благодаря которой старый файл после редактирования аккуратно удаляется. К сожалению, если система при выполнении ващей программы откажет, то вы потеряете все свои старые данные, поэтому значение "" рекомендуется использовать только храбрецам, дуракам и излищне доверчивым.

Вот как можно путем редактирования файла паролей заменить регистрационный shell всех пользователей на /bin/sh:

@ARGV = ("/etc/passwd"); # снабдить информацией операцию "ромб"

$"1 = ".bal<:"; # для надежности записать /etc/passwd.Ьак

while (О) { # основной цикл, по разу для каждой строки файла

# /etc/passwd

s# :[":]*$#:/bin/sh#; # заменить shell на /bm/sh

print; # послать выходную информацию в ARGVOUT: новый

# /etc/passwd

Как видите, эта профамма довольно проста. Однако ее можно заменить всего лищь одной командой с несколькими аргументами командной строки, например:

perl -р -i.bak -е з# :[ :]*$#:/bin/sh# /etc/passwd

Ключ -р охватывает вашу программу циклом while, который включает оператор print. Ключ-i устанавливает значение переменной Ключ-е определяет следующий аргумент как фрагмент Perl-кода для тела цикла, а последний аргумент задает начальное значение массива Qargv.

Более подробно аргументы командной строки рассматриваются в книге Programming Perl и на тап-странице perlnin.



Упражнения

Ответы см. в приложении А.

1. Создайте программу, которая открывает базу данных псевдонимов sendmail и выводит на экран все ее элементы.

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



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 [ 70 ] 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103