Базы данных с записями переменной длины (текстовые)
Многие системные базы данных ОС 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.