С помощью команды make можно также поддерживать свежие версии файлов на разных серверах. Предположим, что на обоих наших почтовых серверах файлы aliases должны быть одинаковыми. Мы решаем отредактировать файл на одном сервере и скопировать его на сервер server2. Инструкция может выглядеть, например, так:

push.aliases.done: $(PDIR)/aliases

scp $(PDIR)/aliases server2:$(PDIR)/aliases

touch $@

Мы копируем файл на serveг2 командой scp, затем применяем команду touch к файлу push.aliases.done. Поскольку этот файл создается после успешной операции копирования, мы можем построить инструкции так, что копирование будет выполняться только в случае необходимости. Мы также можем принудительно скопировать файл, если просто удалим push.aliases.done и введем команду make. Традиционно вводится инструкция clean, которая удаляет все файлы *.done и прочие файлы, сгенерированные автоматически.

В файлах, имена которых оканчиваются на .done, нет ничего особенного. Это обычные файлы с меткой времени или флагом для имени.

Рассмотрим развернутый пример. Имеются два файла, подлежащие индексации после редактирования: aliases и access. Если хотя бы один из них проиндексирован заново, выдается команда перезагрузки Postfix. Кроме того, оба файла копируются на serveг2, если они были изменены. Наконец, команда cd /etc && make выполняется на server2 тогда и только тогда, когда на него был скопирован хотя бы один файл.

Будьте внимательны, создавая инструкции. Правильно указывайте параметры и применяйте команду touch к файлам *.done, если потребуется. Команда make выполнит лишь минимум работы, необходимый для обновления системы.

#

# Makefile для server1

#

NEWALISES=/usr/sbin/newaliases

PDIR=/etc/postfix

POSTMAP=/usr/lосаl/postfix/sbin/postmap

#

# "Команды" высокого уровня

#

all: aliases.done access.done reload_if_needed.done push

push: push.done

reload:

postfix reload

stop:

postfix stop

start:

postfix start

reload_if_needed.done: aliases.done access.done

postfix reload

touch reload_if_needed.done

clean:

rm — f \

$(PDIR)/aliases.pag $(PDIR)/aliases.dir \

$(PDIR)/access.dir $(PDIR)/access.pag \

push.aliases.done push.access.done \

reload_if_needed.done

#

# Инструкции для конкретных файлов,

# которым требуется индексация/регенерация

#

# Если aliases изменится, сгенерировать файлы. pag and.dir

aliases.done: $(PDIR)/aliases.pag $(PDIR)/aliases.dir

$(PDIR)/aliases.pag $(PDIR)/aliases.dir: $(PDIR)/aliases $(NEWALIASES)

# Если access изменится, сгенерировать файлы. pag and.dir

access.done: $(PDIR)/access.dir $(PDIR)/access.pag

$(PDIR)/access.dir $(PDIR)/access.pag: $(PDIR)/access $(POSTMAP) $(PDIR)/access

#

# Копирование

#

push.done: push.aliases.done push.access.done

ssh server2 "cd /etc && make"

touch $@

push.aliases.done: aliases.done

scp $(PDIR)/aliases server2:$(PDIR)/aliases

touch $@

push.access.done: access.done

scp $(PDIR)/access server2:$(PDIR)/access

touch $@

Этот Makefile является для вас хорошей стартовой площадкой. Он довольно сложен, потому что нам нужна гарантия того, что Postfix перезагрузится, лишь когда это абсолютно необходимо.

Такой Makefile избавляет вас от необходимости помнить множество команд, в том числе те, которые необходимы для обновления конкретных файлов. Вы больше не боитесь забыть какую-то команду. Многие сложные процедуры теперь сводятся к двум шагам:

1. Отредактировать нужный файл.

2. Ввести команду make.

Команда make является универсальным инструментом для соединения нескольких автоматизированных процессов. Однажды я должен был объединить несколько процессов и процедур для трех больших сетей. В каждой сети была своя система сопровождения псевдонимов, хостов и прочей административной информации. Разобравшись в процедурах для каждой сети, я построил Makefile для главных серверов этих сетей. Имена инструкций верхнего уровня были одинаковыми для всех трех сетей, но команды, которые они выполняли, для каждой сети были свои.

В мои стратегические планы входило создание нового главного сервера, который в конечном счете заменил бы все серверы, доставшиеся мне, так сказать, в наследство. Первоначально Makefile нового главного сервера просто вызывал команду make на трех главных серверах с помощью команды rsh (это было задолго до появления ssh). Затем я поочередно перенес инструкции на новый сервер. Вначале я решил, что новый главный сервер должен быть единственным источником информации для файла aliases. Я слил файлы aliases всех трех сетей и разместил результат на главном сервере. Протестировав его, я создал инструкции, которые копировали этот объединенный файл на прежние главные серверы так, словно это был их собственный файл. Я поступил аналогичным образом с каждым файлом и каждой базой данных.

Поскольку каждое изменение было незначительным и конкретным, я мог выполнять тестирование итеративно. Произведя буквально несколько сотен изменений, я добился того, что все серверы «пели в унисон». В этот момент мне не составило труда исключить старые главные серверы и поставить новый над всеми клиентами.

♠ Любой файл, автоматически копируемый на другие серверы, должен обязательно содержать в начале комментарий, информирующий других системных администраторов, откуда файл пришел и где его следует редактировать.

Вот комментарий, который я пишу:

# ЭТОТ ФАЙЛ СОПРОВОЖДАЕТСЯ НА СЕРВЕРЕ:

# server1.example.com

# Редактируйте его при помощи команды: xed file.txt

# Если вы отредактируете его на любом другом компьютере,

# он будет перезагружен. БУДЬТЕ ВНИМАТЕЛЬНЫ!

Поскольку в комментарии упоминается xed, я должен пояснить, что это такое. Есть несколько программ с именем xed, но эту конкретную программу можно найти по адресу http://www.nightcoder.com/code/xed. Она вызывает редактор, которым вы обычно пользуетесь ($EDITOR можно установить в vi, pico, emacs и т. д.), после того как заблокирует файл. Это обязательное условие для любого сайта, на котором один компьютер используют несколько системных администраторов. Если вы отслеживаете изменения в файле с помощью RCS, эта система зарегистрирует все попытки отредактировать файл. Вы получаете практически бесконечный откат и журнал, где записано, кто и что изменил. Если вы заметите, что последний месяц система ведет себя как-то странно, то проверьте, кто редактировал файл месяц назад. Будьте снисходительны: все мы допускаем ошибки.

Сложные задачи, выполняемые однократно

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

Инкапсуляция сложной команды

Бывает, что на создание команды, которая делает именно то, что нужно, уходит несколько часов. Например, есть программа, создающая ISO-образы диска для последующей записи на CD-ROM. На странице ее описания перечислены сотни параметров, но команда, позволяющая создать образ, читаемый в Windows, UNIX и Mac OS X, достаточно проста:

$ mkisofs — D -l — J -r — L -f — P "Имя автора" — V "метка диска" — copyright \ copyright.txt — о disk.iso /directory/of/files

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