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

       

Работа с дисковыми квотами Perlсценарии


Первый способ требует некоторой хитрости с нашей стороны. Совсем недавно мы упоминали процесс ручной установки дисковых квот: edquota вызывает редактор, в котором пользователь редактирует небольшой текстовый файл, после чего эти изменения используются для обновления информации о квотах. Не существует никаких указаний на то, какие данные необходимо вводить, чтобы внести изменения. В действительности, не существует даже ограничений на то, какой редактор будет применяться. Все, что нужно команде edquota, это программа, которую можно запустить и которая необходимым образом изменит маленький текстовый файл. Подойдет любой допустимый путь (заданный переменной окружения ;TI IOR) к такой программе. Почему бы не указать программе edquota сценарий на Perl? Давайте и рассмотрим такой сценарий в нашем следующем примере.

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

Второй копии программы необходимо сообщить, что именно она должна изменить по требованию исходной программы. Как она получает эту информацию из первой копии, вызвавшей edquota, менее очевидно, чем этого бы хотелось. В странице руководства по edquota сказано: «Вызывается редактор vi(l), если только в переменной EDITOR не указано иное». Идея передать аргументы командной строки через EDITOR или другую переменную окружения довольно опасна хотя бы потому, что мы не знаем, как на это отреагирует утилита edquota. Поэтому нам придется полагаться на один из методов межпроцессного взаимодействия, доступных в Perl. Например, два процесса могут:

  • Передавать друг другу временный файл
  • Создать именованный канал и общаться по нему
  • Передавать AppleEvents (в MacOS)
  • Использовать объект синхронизации (inutex) или оговоренные ключи реестра (в NT/2000)
  • Общаться через сокеты
  • Использовать разделяемую память

И так далее. От вас как от программиста зависит, какой метод вы выберете, хотя зачастую определять выбор будут данные. Рассматривая их, вы будете принимать во внимание:



  • Направление соединения (одно- или двунаправленное?)
  • Частоту соединения (будет передано одно сообщение или несколько кусочков?)
  • Размер данных (будет это 10-мегабайтный файл или 20 символов?)
  • Формат данных (будет это двоичный файл или просто текст фиксированной ширины, разделенный определенным символом?)

Наконец, учитывайте то, насколько сложным вы хотите сделать свой сценарий.

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

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

$edquota = "/usr/etc/edquota"; и путь к edquota

Sautoedq = "/usr/adm/autoedquota"; ц полный путь к этому сценарию

ft это первый или второй запуск?

ft если присутствует более одного аргумента - это первый запуск

if ($»ARGV > 0) {

&ParseArgs;

&CallEdquota; }

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

else {

&EdOuota(); }

Рассмотрим код, вызываемый при первом запуске и используемый для анализа аргументов и вызова edquota через канал:

sub ParseArgsf

use Getopt: :Std;

# для обработки параметров

# Устанавливаем переменную $opt_u равной идентификатору и пользователя,

$opt_f - равной имени файловой системы,

$opt_s - в значение для мягкого ограничения и

$opt_h -К в значение для жесткого ограничения getopt("u:f:s:h:");

двоеточие говорит о том, что у этого

# ключа есть аргумент die "ИСПОЛЬЗОВАНИЕ:

$0 -u uid -f <fsystem> -s <softq> -h <nardq>\n"

if (<$opt_u || !$opt_f || !$opt_s || !$opt_n); }

sub CallEdquotaf

$ENV{"EDITOR"} = Sautoedq;

записываем в

# переменную окружения EDITOR путь к нашему сценарию

operKEPROCFSS. "|$edquota $opt_u") or die

"Невозможно запустить edquota :$! \r,":

посылаем измененные строки во вторую копию сценария

print EPROCESS "$opt_f|$opt^s|$opt_.h\n";

close(EPROCESS); }

Вот вторая часть выполняемого действия:

sub EdOuota {

Stfile = $ARGV[0];

получаем имя временного файла edquota

open(TEMPFILE, Stfile) or die "Невозможно открыть временный файл

# открываем файл-черновик, можно было бы и использовать и

new_tmpfile() open(NEWTEMP, ">$tfile.$$") or die "

Невозможно открыть временный файл-черновик Stfile.$$:$!\";

# получаем строку ввода из первого вызова и отсекаем символ \

chomp($change = <STDIN>);

my($fs,$soft,Shard) = split(/\|/,$change);

разбираем ответ

считываем из временного файла строку. Если она содержит

информацию о файловой системе, которую мы хотим

изменить, изменяем эти значения. Записываем строку

(вероятно, измененную) в черновик, while (<TEMPFILE>){

перезаписываем временный файл измененным черновиком,

так что изменения передаются edquota rename("Stfile.$$",Stfile)

or die "Невозможно переименовать

$tfile.$$ в $t*ile:$!\n":

}

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



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