Изучаем Perl

       

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


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

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

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

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

і. Оно играет важную роль и будет сейчас рассмот-рено.

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

$ARGV = shift 6ARGV;

open(ARGV,"<$ARGV") ;

rename($ARGV,"$ARGV$AI"); ## INPLACE ## unlink($ARGV); ## INPLACE ##

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

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


Типичные значення переменной $ЛI — .bak или ~, т.е. резервные файлы создаются почти так же, как зто делается в текстовом редакторе. Странное и полезное значение $ЛI — пустая строка (""), благодаря которой старый файл после редактирования аккуратно удаляется. К сожалению, если система при выполнении вашей программы откажет, то вы потеряете все свои старые данные, позтому значение "" рекомендуется использовать только храбрецам, дуракам и излишне доверчивым.

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

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

$"1

== ".bak"; # для надежности записать /etc/passwd.bak

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

# /etc/passwd s#: (л: ] *$#:/bin/sh#; # заменить shell на /bin/sh print; # послать выходную информацию в ARGVOUT: новий

# /etc/passwd

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

perl -р -і.bak -е 's#: [л:]*$#:/bin/sh#' /etc/passwd

Ключ -р охватывает вашу программу циклом while, который включает оператор print. Ключ -і устанавливает значение переменной $^1. Ключ -е определяет следующий аргумент как фрагмент Perl-кода для тела цикла, а последний аргумент задает начальнеє значение массива @argv.

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


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