Serveг1» make aliases.db
newaliases
Done updating aliases Serverltt
Вот так! Команда make прочитала свой файл конфигурации, выяснила, что файл aliases новее, чем aliases.db (сравнив их метки времени), и определила, что запуск команды newaliases приведет к обновлению файла aliasesAb. Попробуем запустить make еще раз:
Serverltt make aliases.db
Server18
Сообщение об обновлении не выводится. Почему? Потому что теперь согласно меткам времени ничего делать не нужно, ведь файл aliases. db новее файла aliases. Команда make ленива и выполняет минимум работы, необходимый для получения результата. Она принимает решения на основе меток времени в файлах.
Вот еще один пример кода в файле Makefile:
filel.output: filel.input
commancH file.output
file2,output: file2,input command2 file2.input >$@
В первом случае команда, которую следует выполнить, использует стандартные потоки ввода/вывода stdin и stdout (перенаправление обозначено символами < и >), чтобы прочитать fileXnput и произвести запись в file, output. Второй фрагмент аналогичен первому, но команда берет имя входного из командной строки и перенаправляет вывод... куда? Конструкция $§ означает «файл, создаваемый этой инструкцией», в нашем случае это file2.output. Почему не придумали мнемоническое обозначение, вроде $те или $this? Неизвестно. Вам совсем не обязательно использовать обозначение $@, но с ним вы будете выглядеть умнее своих коллег.
Команда make, запущенная без параметров, выполняет первую инструкцию из файла Makefile. По традиции первая инструкция называется all, и она выполняет все инструкции, которые должны быть выполнены по умолчанию. Таким образом, запуск make выполняет все важные инструкции. Возможно, это будут не все инструкции, а лишь те, которые вы хотите выполнить по умолчанию. Эта инструкция может выглядеть, например, так:
all: aliases.db access,db
Команда make без параметров проверяет, не обновлялись ли файлы ali- ases.db и access.db. Поскольку в инструкции all не указано никакой команды, файл с именем all создан не будет. Тогда make будет считать, что файл all устарел («не существует» эквивалентно «устарел»). Вскоре вы поймете важность такой интерпретации.
Не будем забывать, что команда make ленива. Если файл access.db устарел, а второй файл - нет, то она выполнит только действия по обновлению access.db. Если для обновления файла потребуются какие-то дополнительные действия, а для них что-то еще, то команда make рационально выполнит только необходимый минимум работы.
Кроме инструкции all, я обычно пишу еще пару-тройку полезных команд:
reload:
postfix reload
stop:
postfix stop
start:
postfix start
Обсудим, что они означают. Если я введу make reload, команда make заметит отсутствие файла reload и запустит команду postfix reload в надежде, что та создаст такой файл. Ага! Я ее перехитрил! Указанная команда перегружает конфигурацию Postfix. Она не создает никакого файла reload! Когда я выполню make reload в следующий раз, команда make поступит точно так же. Другими словами, если вы хотите, чтобы некоторое действие выполнялось всегда, сделайте так, чтобы инструкция не создавала файл, который надеется создать команда make.
Имея код, приведенный выше, я могу перезагрузить, остановить и запустить postfix, введя команду make reload, make stop и make start соответственно. Если есть другие процессы, которые требуется остановить (например, IMAP сервер, веб-клиент электронной почты и т. д.), я включу необходимые команды в инструкции. Мне не нужно запоминать эти команды.
Сейчас я должен признать, что раньше чуть-чуть передернул. Я сказал, что каждая инструкция начинается с имени файла, который нужно создать, затем идет двоеточие, а затем - список файлов, образующих главный. Так вот, команде make неизвестно, состоит ли в действительности создаваемый файл из перечисленных. У нее нет способа проверить это. Элементы, указанные после двоеточия, являются всего лишь параметрами, которые не должны быть устаревшими.
Приведу простой пример реального файла Makefile, который запускает Postfix и содержит инструкции обновления индекса для файлов aliases и access. В начале файла вы заметите константы (NEMALJSES, FDR и т. д.), используемые далее в файле. Обратный слэш (\) в конце строки кода служит для переноса длинных строк:
NEWALISES=/usr/sbin/newa liases PDIR=/etc/postfix
PQSTMAP=/u5r/local/postfix/sbin/post[tiap И Команды
all: $(PDlft)/aliases.pag ${POIR)/aliases,dir \
$(PDIR)/access.dir S(PDIR)/access.pag reload
reload:
postfix reload
stop:
postfix stop
start:
postfix start
#
-
Когда aliases изменится, сгенерировать файлы ,pag and dir
-
S(PDIR)/aliases,pag $(PDIH)/aliases,dir: S(PDIR)/aliases $(NEWALIASES)
tf
tt Когда access изменится, сгенерировать файлы ,pag and ,dir i
$(POIFi)/access.dir $(PDIR)/access. pag: t(POIR)/access $(P0STHAP) I(PDIR)/access
Теперь я могу отредактировать файл aliases или access и ввести команду make. Мне не нужно помнить, что команды обновления индексов сильно различаются. Я не должен помнить о необходимости перезагружать конфигурацию Postfix, потому что соответствующая команда включена в инструкцию all. Конструкция reload в конце all будет каждый раз запускать эту инструкцию.
С помощью команды make можно также поддерживать свежие версии файлов на разных серверах. Предположим, что на обоих наших почтовых серверах файлы aliases должны быть одинаковыми. Мы решаем отредактировать файл на одном сервере и скопировать его на сервер server2. Инструкция может выглядеть, например, так:
push,aliases.done: $(PDIR)/aliases
scp $(PDIR)/aliases server2:$(PDIR)/aliases touch
Мы копируем файл на served командой scp, затем применяем команду touch к файлу push.aliases.done. Поскольку этот файл создается после успешной операции копирования, мы можем построить инструкции так, что копирование будет выполняться только в случае необходимости. Мы также можем принудительно скопировать файл, если просто удалим push.aliases.done и введем команду make. Традиционно вводится инструкция clean, которая удаляет все файлы *.done и прочие файлы, сгенерированные автоматически.
В файлах, имена которых оканчиваются на .done, нет ничего особенного. Это обычные файлы с меткой времени или флагом для имени.
Рассмотрим развернутый пример. Имеются два файла, подлежащие индексации после редактирования: aliases и access. Если хотя бы один из них проиндексирован заново, выдается команда перезагрузки Postfix. Кроме того, оба файла копируются на served, если они были изменены. Наконец, команда cd /etc && make выполняется на server2 тогда и только тогда, когда на него был скопирован хотя бы один файл.
Будьте внимательны, создавая инструкции. Правильно указывайте параметры и применяйте команду touch к файлам *.done, если потребуется. Команда make выполнит лишь минимум работы, необходимый
для обновления системы. #
NEWAUSES=/usr/sbin/newaliase$ PDIR=/etc/postfix
P0STMAP=/usr/local/postfix/5bin/po5tmap :#
О "Команды" высокого уровня
all: aliases,done access.done reload_if_needed,done push
push: push,done
reload:
postfix reload
stop:
postfix stop
start:
postfix start
rsload_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
s
в Инструкции для конкретных файлов,
s которым требуется индексация/регенерация |
-
Если aliases изменится, сгенерировать файлы .рад and .dir
aliases,done: t(PDIR)/aliases.pag J(POIR)/aHases.dir
$(POIR)/aliases рад $(PDIR)/aliases,dir: $(PDIfi)/aliases ${NEWALIASES)
я Если access изменится, сгенерировать файлы ,pag and .dir
access.done: $(PDIR)/access,dir $(PDIR)/access.pag
$(PDIR)/access.dir $(POIR)/access.pag: $(PDIR)/access $(P0STMAP) J(PDIR)/access
# Копирование i
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 S@
Этот Makefile является для вас хорошей стартовой площадкой. Он довольно сложен, потому что нам нужна гарантия того, что Postfix перезагрузится, лишь когда это абсолютно необходимо.
Такой Makefile избавляет вас от необходимости помнить множество команд, в том числе те, которые необходимы для обновления конкретных файлов. Вы больше не боитесь забыть какую-то команду. Многие сложные процедуры теперь сводятся к двум шагам:
-
Отредактировать нужный файл.
-
Ввести команду make.
Команда make является универсальным инструментом для соединения нескольких автоматизированных процессов. Однажды я должен был объединить несколько процессов и процедур для трех больших сетей. В каждой сети была своя система сопровождения псевдонимов, хостов и прочей административной информации. Разобравшись в процедурах для каждой сети, я построил Makefile для главных серверов этих сетей. Имена инструкций верхнего уровня были одинаковыми
для всех трех сетей, но команды, которые они выполняли, для каждой сети были свои.
В мои стратегические планы входило создание нового главного сервера, который в конечном счете заменил бы все серверы, доставшиеся мне, так сказать, в наследство. Первоначально Makefile нового главного сервера просто вызывал команду make на трех главных серверах с помощью команды rsh (это было задолго до появления ssh). Затем я поочередно перенес инструкции на новый сервер. Вначале я решил, что новый главный сервер должен быть единственным источником информации для файла aliases. Я слил файлы aliases всех трех сетей и разместил результат на главном сервере. Протестировав его, я создал инструкции, которые копировали этот объединенный файл на прежние главные серверы так, словно это был их собственный файл. Я поступил аналогичным образом с каждым файлом и каждой базой данных.
Поскольку каждое изменение было незначительным и конкретным, я мог выполнять тестирование итеративно. Произведя буквально несколько сотен изменений, я добился того, что все серверы «пели в унисон». В этот момент мне не составило труда исключить старые главные серверы и поставить новый над всеми клиентами.
Любой файл, автоматически копируемый на другие серверы, должен обязательно содержать в начале комментарий, информирующий других системных администраторов, откуда файл пришел и где его следует редактировать.
Вот комментарий, который я пишу:
-
ЭТОТ ФАЙЛ СОПРОВОЖДАЕТСЯ НА СЕРВЕРЕ:
-
server1.example.com
№ Редактируйте его при помощи команды: xed file.txt
№ Если вы отредактируете его на любом другом компьютере,
Я он будет перезагружен. БУДЬТЕ ВНИМАТЕЛЬНЫ!
Поскольку в комментарии упоминается xed, я должен пояснить, что это такое. Есть несколько программ с именем xed, но эту конкретную программу можно найти по адресу http://www.nightcoder.com/code/ xed. Она вызывает редактор, которым вы обычно пользуетесь ($EDIIOR можно установить в vi, pico, emacs и т. д.), после того как заблокирует файл. Это обязательное условие для любого сайта, на котором один компьютер используют несколько системных администраторов. Если вы отслеживаете изменения в файле с помощью RCS, эта система зарегистрирует все попытки отредактировать файл. Вы получаете практически бесконечный откат и журнал, где записано, кто и что изменил. Если вы заметите, что последний месяц система ведет себя как-то странно, то проверьте, кто редактировал файл месяц назад. Будьте снисходительны: все мы допускаем ошибки.
Сложные задачи, выполняемые однократно
Автоматизация работы предполагает, что, выполняя нечто сложное, мы записываем последовательность действий. В этом случае повторить действия впоследствии много проще. Это как если бы мы строили для себя некоторую подстраховку.
Инкапсуляция сложной команды
Бывает, что на создание команды, которая делает именно то, что нужно, уходит несколько часов. Например, есть программа, создающая ISO-об- разы диска для последующей записи на CD-ROM. На странице ее описания перечислены сотни параметров, но команда, позволяющая создать образ, читаемый в Windows, UNIX и Mac OS X, достаточно проста:
$ mklsofs -D -1 -J -г -L -f -P "Имя автора" -V "метка диска" -copyright \ copyright.txt -о disk.iso /directory/of/files
Конечно, все можно проделать с помощью графического интерфейса, но вы не получите никакого удовольствия (а также возможности создать сценарий).
Эта команда позволяет вам делать то, что недоступно в большинстве графических интерфейсов, например сообщать об авторских правах, указывать имя автора и т. д.
Она хорошо встраивается в JJAT-файл (в DOS) или в сценарий оболочки UNIX/Linux.
Вот пример сценария makeimagel, в котором используется эта команда: ft! /Ып/bash
mkisofs -0 -1 -J -г -L -f -P "Limoncelli" -V 'date -u +MU $*
Конструкция 'date -u ' создает метку тома, содержащую теку
щую дату.
Я долго не мог создавать хорошие сценарии, потому что не знал, как обрабатывать параметры командной строки. Расскажу, как следует копировать их в сценарий.
Конструкция $* в сценарии означает «любые элементы командной строки». Если вы введете:
Достарыңызбен бөлісу: |