Книга: Тайм-менеджмент для системных администраторов

Простые задачи, выполняемые часто

Простые задачи, выполняемые часто

Приведу несколько примеров часто выполняемых простых задач. Обращаю внимание системных администраторов Windows, что эти примеры ориентированы на UNIX/Linux. Тем не менее, общие принципы применимы ко всем операционным системам.

Сокращения для команд

Большинство систем с командной строкой имеет ту или иную возможность создания псевдонимов. Это позволяет вам создавать новые команды на основе существующих. В каждой операционной системе принят свой синтаксис. В системе UNIX имеется множество языков оболочки (командной строки), самыми популярными из которых являются bash и csh. Они сильно различаются, и вы заметите, что, в первую очередь, в bash приходится употреблять знак равенства. Я приведу примеры для обеих оболочек.

? Примеры на bash будут работать в любой оболочке, смоделированной по оригинальной Bourne Shell, созданной Стивом Борном (Steve Bourne) (/bin/sh), например в Korn Shell (/bin/ksh) и Z Shell (/bin/zsh). Аналогичным образом примеры на csh будут работать в любой оболочке, имеющей корни csh, включая оболочку Tenex С shell (/bin/tcsh).

Как попасть в нужный каталог

Мне нередко приходится выдавать команду cd для перехода в каталог с очень длинным путем. Вот пример использования псевдонима:

bash:
alias book='cd "tal/projects/books/time/chapters'
csh:
alias book 'cd "tal/projects/books/time/chapters'

Теперь я могу набирать на клавиатуре book каждый раз, когда мне нужно перейти в каталог, где находятся файлы для текущей книги. Если я возьмусь написать другую книгу, я обновлю этот псевдоним. (Я ввожу «book» в течение последних шести лет!)

Это не только позволяет сэкономить на вводе. Вы избавлены от необходимости запоминать путь к каталогу. Освободить свою память всегда полезно.

Чтобы сделать псевдоним постоянным, вы должны добавить указанную строку в файл .profile, bashrc (bash) или .cshrc (csh). Эти файлы считываются только во время входа в систему, так что либо выйдите из системы и войдите обратно, либо введите команду source, чтобы файлы были прочитаны снова.

bash:
. "/.profile
csh:
source "/.cshrc

(Примечание: в bash эта команда обозначается точкой.)

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

bash:
alias inva='cd "tal/projects/inventory/groupa; export INVSTYLE=A'
alias invb='cd "tal/projects/inventory/groupb; export INV3TYLE=B'
csh:
alias inva 'cd "tal/projects/inventory/groupa; setenv INVSTYLE A'
alias invb 'cd "tal/projects/inventory/groupb; seteiw INVSTYLE B'

Вместо точки с запятой можно поставить двойной амперсанд для обозначения такого условия: «Выполнить следующую команду только в том случае, если первая завершилась удачно». Этот прием полезен, если нужно избежать выполнения команды не в том каталоге. Например, вы хотите перейти в некоторый каталог и поставить там метку времени в журнале. Однако если команда cd не будет выполнена (сервер недоступен), не следует ставить метку времени в журнале текущего каталога.

bash;
alias rank='cd /home/rank/data && date». log'
csh:
alias rank 'cd /home/rank/data && date». log'

? Не пытайтесь превратить одну операционную систему в другую. Псевдонимы сами по себе хороши, но ими нельзя злоупотреблять. Я часто видел людей, создающих десятки псевдонимов для того, чтобы симулировать DOS в UNIX. Думаю, это плохая идея. Так вы никогда не научитесь работать в UNIX, а, оказавшись за чужим компьютером, где нет ваших псевдонимов, попадете впросак.

Сокращения для имен компьютеров

Если вам приходится снова и снова вводить имена каких-то компьютеров, вы можете сэкономить немного времени, создав псевдонимы. Например, если вы часто обращаетесь к серверу ramanujan.company.com, то можете создать псевдоним (запись DNS CNAME) ram.company.com. Это имя чуть проще набирать на клавиатуре.

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

Как правило, часто обращаясь к какому-то серверу, я почти во всех случаях использую SSH (Secure SHell). Это безопасная (криптографически защищенная) альтернатива telnet и rsh. С ее помощью вы также можете копировать файлы (вводя scp вместо гср), и многие программы, например rsync, работают с SSH. Система Unix SSH (OpenSSH и ее сестры) позволяет вам установить псевдонимы, известные всем пользователям UNIX, либо псевдонимы, доступные только вам.

Чтобы ограничиться только своими SSH-сеансами, добавьте псевдонимы в файл ~/.ssh/config. Если же вы хотите предоставить псевдонимы в распоряжение всех пользователей, добавьте псевдонимы в файл /etc/ssh_config или /etc/ssh/ssh_config в зависимости от конфигурации вашей системы. В следующем примере я создаю псевдоним es, чтобы избавить себя от необходимости вводить www.everythingsysadmin.com:

Host es
HostName www.everythingsysadmin.com

Теперь я могу не только вводить ssh es вместо ssh www.everythingsysadmin.com, но и использовать этот псевдоним в командах scp, sftp, rsync и других. Более того, сценарии и программы, которые я не могу изменить, будут автоматически воспринимать новые настройки. Вот несколько примеров:

$ ssh es
$ scp file.txt es:/tmp/
$ rsync ex:/home/project/alpha "/project/alpha

Я использую ssh es так часто, что создал псевдоним на уровне оболочки:

bash:
alias es='ssh es'
csh:
alias es 'ssh es'

В результате теперь я могу вводить в командной строке es, чтобы войти в систему, или с помощью всех тех же двух букв обозначить хост в командах scp или rsync. Ведь круто?

Возникает соблазн создать двухбуквенные псевдонимы для всех серверов на свете. Однако вскоре вы обнаружите, что вспоминаете обозначения дольше, чем вводите имена с клавиатуры. Я ограничил себя несколькими серверами, к которым обращаюсь через SSH.

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

$ ssh — х -о RSAAuthentication=yes — о PasswordAuthentication=yes — о
ChallengeResponseAuthentication=no -1 peter.example.net

Я мог бы установить псевдоним, но вместо этого изменил конфигурацию SSH, и все системы, использующие SSH, работают, как надо. Если сценарий, который я не могу изменить, использует SSH для доступа к тому серверу, он воспримет эти настройки.

Соответствующие строки в моем файле ~/.ssh/config выглядят так:

Host peter.example.net
ForwardX11 no
RSAAuthentication yes
PasswordAuthentication yes
ChallengeResponseAuthentication no
Compression no
Protocol 1

У SSH-клиентов для Windows обычно есть графический интерфейс, позволяющий сохранить настройки профиля, которые следует использовать для конкретного сервера (или нескольких серверов).

Чем больше вы знаете про SSH, тем больше вы можете сделать. Есть много хороших книг и электронных справочников с подробным описанием SSH, например «SSH, The Secure Shell: The Definitive Guide» (SSH. Безопасная оболочка: полное руководство), O'Reilly. Если в SSH и есть то, что должен знать каждый системный администратор (но, возможно, не знает), то это следующее: как настроить открытые/закрытые (public/private) ключи, чтобы, не снижая уровень безопасности, исключить необходимость ввода пароля при обращении с одного конкретного компьютера к другому через SSH.

Make-файл для каждого хоста

Этот раздел относится исключительно к системам UNIX/Linux. Тот, кто работает в Windows, может его пропустить.

В системах UNIX/Linux важная информация часто хранится в обычных текстовых файлах, которые можно отредактировать вручную. В некоторых случаях после редактирования файла необходимо выполнить специальную команду, чтобы сообщить системе, что информация изменилась.

Например, после редактирования файла /etc/aliases (к которому обращаются sendmail, Postfix и различные пакеты пересылки почты), вы должны выполнить команду newaliases. Ее легко запомнить, не так ли?

А какую команду надо выполнить после редактирования файла transports программы Postfix? Возможно, newtransports? Нет, это было бы слишком просто. Вы должны выполнить postmap transports. А еще есть команда т4, которую нужно выполнить после редактирования m4-файлов и т. д., и т. п.

Как обратиться к нужному серверу с помощью SSH

Предположим, у вас три сервера: server1.example.com, server2.example.com и server3.example.com. На них расположено много вебсайтов, и вам трудно запомнить, какой сайт на каком сервере. Где находится сайт www.everythingsysadmin.com — на первом или третьем сервере? Вы думаете, что на третьем, но не исключено, что его перенесли на второй из-за нехватки места на диске. Зачем вообще все это запоминать? Нет никакой необходимости редактировать файл конфигурации. Просто укажите имя хоста веб-сайта в команде SSH! Например, введите ssh www.everythingsysadmin.com, и вы окажетесь на нужном сервере. Это довольно очевидно, но вы не поверите, как часто люди забывают о такой возможности!

У кого найдется время заучить все команды, которые нужно выполнить после редактирования файлов? Такие подробности должен помнить сам компьютер.

На помощь приходит команда make! Вы можете считать ее программным инструментом, чем-то вроде компилятора. Она позволяет вам указать, какую команду нужно запускать для обновления одного файла, если в другой были внесены изменения.

? Команда make является одним из самых мощных инструментов системного администрирования, которые когда-либо были изобретены. Я слышал, что программисты тоже считают ее полезной!

У команды make больше функциональных возможностей, чем было мужей у Элизабет Тейлор, поэтому я лишь вкратце представлю ее вам. (Прочитав только первые две главы практически любой книги, посвященной команде make, вы узнаете 99 % того, что необходимо для большинства задач системного администрирования, и в 10 раз больше, чем знают коллеги.)

Краткое описание команды make

Команда make читает файл конфигурации, весьма уместно именуемый Makefile. В этом файле находятся инструкции, которые сообщают команде make, что она должна делать.

Каждая инструкция имеет такой формат:

whole: partA partB partC
команда, создающая whole

Инструкция начинается с имени файла, который должен быть создан. Затем стоит двоеточие, после которого указаны файлы, необходимые для построения главного.[6] В этом примере создается файл whole, и устанавливается соотношение между partA, partB и partC. Если один из них будет отредактирован, мы должны будем выполнить команду, создающую whole.

Приведу вполне реальный пример:

aliases.db: aliases
newaliases
@echo Done updating aliases

Этот код означает, что, если файл aliases будет изменен, команда newaliases регенерирует файл aliases.db. В случае успеха будет выведено сообщение «Done updating aliases» (Выполнено обновление aliases).

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

Обновление файла не происходит автоматически. Вы должны только запустить команду make:

Server1# make aliases.db
newaliases
Done updating aliases
Server1#

Вот так! Команда make прочитала свой файл конфигурации, выяснила, что файл aliases новее, чем aliases.db (сравнив их метки времени), и определила, что запуск команды newaliases приведет к обновлению файла aliasesAb. Попробуем запустить make еще раз:

Server1# make aliases.db
Server1#

Сообщение об обновлении не выводится. Почему? Потому что теперь согласно меткам времени ничего делать не нужно, ведь файл aliases.db новее файла aliases. Команда make ленива и выполняет минимум работы, необходимый для получения результата. Она принимает решения на основе меток времени в файлах.

Вот еще один пример кода в файле Makefile:

file1.output: file1.input
command1 <file.input> file.output
file2.output: file2.input
command1 file2.input >$@

В первом случае команда, которую следует выполнить, использует стандартные потоки ввода/вывода stdin и stdout (перенаправление обозначено символами < и >), чтобы прочитать fileXnput и произвести запись в file, output. Второй фрагмент аналогичен первому, но команда берет имя входного из командной строки и перенаправляет вывод… куда? Конструкция $@ означает «файл, создаваемый этой инструкцией», в нашем случае это file2.output. Почему не придумали мнемоническое обозначение, вроде $the или $this? Неизвестно. Вам совсем не обязательно использовать обозначение $@, но с ним вы будете выглядеть умнее своих коллег.

Команда make, запущенная без параметров, выполняет первую инструкцию из файла Makefile. По традиции первая инструкция называется all, и она выполняет все инструкции, которые должны быть выполнены по умолчанию. Таким образом, запуск make выполняет все важные инструкции. Возможно, это будут не все инструкции, а лишь те, которые вы хотите выполнить по умолчанию. Эта инструкция может выглядеть, например, так:

all: aliases.db access.db

Команда make без параметров проверяет, не обновлялись ли файлы aliases.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. В начале файла вы заметите константы (NEWALISES, PDIR и т. д.), используемые далее в файле. Обратный слэш () в конце строки кода служит для переноса длинных строк:

NEWALISES=/usr/sbin/newaliases
PDIR=/etc/postfix
POSTMAP=/usr/local/postfix/sbin/postmap
# Команды
all: $(PDIR)/aliases.pag $(PDTR)/aliases.dir
$(PDIP)/access.dir $(PDIR)/access.pag reload
reload:
postfix reload
stop:
postfix stop
start:
postfix start
#
# Когда aliases изменится, сгенерировать файлы. pag and.dir
#
$(PDIR)/aliases.pag $(PDIR)/aliases.dir: $(PDIR)/aliases $(NEWALIASES)
#
# Когда access изменится, сгенерировать файлы. pag and.dir
#
$(PDIR)/access.dir $(PDIR)/access.pag: $(PDIR)/access $(POSTMAP) $(PDIR)/access

Теперь я могу отредактировать файл aliases или access и ввести команду make. Мне не нужно помнить, что команды обновления индексов сильно различаются. Я не должен помнить о необходимости перезагружать конфигурацию Postfix, потому что соответствующая команда включена в инструкцию all. Конструкция reload в конце all будет каждый раз запускать эту инструкцию.

С помощью команды 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, эта система зарегистрирует все попытки отредактировать файл. Вы получаете практически бесконечный откат и журнал, где записано, кто и что изменил. Если вы заметите, что последний месяц система ведет себя как-то странно, то проверьте, кто редактировал файл месяц назад. Будьте снисходительны: все мы допускаем ошибки.

Оглавление книги


Генерация: 1.518. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз