RFC (Request for Comments, Запрос на комментарии) - серия документов, публикуемая сообществом исследователей и разработчиков, руководствующихся практическими интересами, в которой описывается набор протоколов и обобщается опыт функционирования Интернет.
Итак, у меня имеется в распоряжении машина: FreeBSD **.ns0.ru 4.9-STABLE FreeBSD 4.9-STABLE #7: Wed Apr 7 22:30:54 MSD 2004 xlwolf@**.ns0.ru:/usr/obj/usr/src/sys/NS i386. Есть доступ администратора. С чего начать? Конечно же, почитать инструкцию к FreeBSD. Кроме тонны книжек, которые уже сломали не одну твою полку, есть еще и электронный справочник по командам, с помощью которых ты общаешься с FreeBSD.
Конечно, хорошо бы общаться с сервером при помощи голоса, но что будет, если вместо "rm –fr ." тот услышит "rm –fr /". Лучше уж вводить команды вручную. А как узнать, что делает определенная команда (например, rm), какие у нее есть параметры и что они значат (например "-fr")? Обо всех командах и рассказано в man. Культпоход в мир Мануала начнем с команды
# man man
исполнив которую ты узнаешь, что же такое творит команда man. Теперь запусти команду man rm – и покажется мануал по утилите rm. А для того, чтобы ты понял смысл написанного, рассмотрим то, что man отображает на экране. Для отображения мануалов по умолчанию используется программа More. Итак, мануал по какой-либо команде состоит из нескольких частей:
NAME – имя самой команды, ее аналогов и краткое описание команды.
SYNOPSIS – описание синтаксиса данной команды.
DESCRIPTION – этот раздел дает подробное описание того, что делает программа и какие параметры ей можно передавать.
NOTE – здесь описаны некоторые замечания по команде. В частности, по команде rm объясняется, как можно выполнять удаление нетривиальных файлов, например, вида "-filename".
SEE ALSO – очень полезный раздел, так как тут отображаются команды, которые связаны с этой командой.
BUGS – здесь описаны известные ошибки, которые еще не исправлены.
Далее идут некоторые другие секции, которые не очень интересы, кроме одной, представляющей исторический интерес: HISTORY – здесь описывается, когда и в какой версии *nix впервые появилась данная команда.
Вроде бы все понятно, но если приглядеться, то в разделе SEE ALSO можно найти какие-то цифры рядом с командами в скобках. Зачем нужны эти неопознанные цифровые объекты? Для того чтобы все-таки опознать их, нужно посмотреть, откуда берет команда man эти самые страницы мануалов. Самое правильное – пойти в бинарник man, куда он может обращаться в пределах файловой системы. Именно это и сделаем:
# strings /usr/bin/man | grep “/”
Из всех строчек привлекает внимание запись /etc/manpath.config. После исследования этого файла становится понятно, что здесь описывается и где находятся все мануалы в системе. А основные мануалы лежат в /usr/share/man. Вот и они! И много как… man1 man2 man3... И что значат эти цифры? Мануалы структурированы по назначению команд, которые они описывают. Итак, имеем классификацию разделов:
Man1 - пользовательские команды (ls, cd, rm).
Man2 – системные вызовы (mkdir(), ioctl()).
Man3 – различные функции (printf(), sin(), abs()).
Также существуют и man7 и man8 и man9, но о них ты теперь сможешь узнать без труда сам зайдя в каталог /usr/share/man/man8.
А если вдруг мне захотелось написать свою собственную программу под *nix? Правила хорошего тона предписывают в этом случае написать мануал к ней и поместить его в нужную папку. Но и это еще не все. Так как мой мануал может занять слишком много места, то я его заархивирую. Именно так и сделано большинство мануалов. Чаще всего для этого используется gzip. Архивирование происходит при помощи очень простой команды:
# gzip <имя_файла>
То есть если мой мануал будет называться leet_syscall.2, то написав
# gzip leet_syscall.2
я получу вместо файла leet_syscall.2, файл leet_syscall.2.gz. И размер файла уже другой. Если вдруг оказалось, что файл архивировать не нужно, то всегда можно сделать обратную операцию
# gzip –d leet_syscall.2.gz
и получить исходный файл. Также при работе с архивами часто бывает нужно, а иногда просто интересно узнать, что скрывается за личиной архива. В таком разоблачении поможет параметр "-l", то есть:
# gzip –l leet_syscall2.gz
Кроме gzip’а существует еще масса архиваторов. Рассмотрим наиболее эффективный из них – bzip2. У него совершенно особый алгоритм сжатия, и сжимает он лучше, чем gzip. Я провел следующий опыт: взял ~2 Гб текста (словари) и сжал его сночала rar’ом, потом эти же два Гб - с помощью Tar, потом - bzip2. Несмотря на отсутствие у bzip2 высоких скоростей, в плане степени сжатия он оказался более эффективным, чем RAR.
Теперь об использовании bzip2 – и снова к мануалам. Смысл работы с bzip2 такой же, как и с gzip – без параметров; сжимаешь указав только имя файла, а параметр "-d" разожмет архив. Важная особенность: ключ "-f" указывает на то, что при разархивировании необходимо перезаписывать файлы, если они уже существуют. Теперь я знаю, как экономить место на диске, но стоит уделить теперь внимание другому аспекту моей программы и мануала к ней. Архиваторы – это, конечно, хорошо, но ведь я пишу программу только для root’а, так что я не хочу, чтобы обычные пользователи в системе могли узнать об этой программе и о том, как она работает. Но это все я описал в мануале к этой программе. Вот незадача. Но проблему опять же мне поможет решить команда man! Посмотрю-ка я мануал к команде access:
# man access
В самом верху надпись ACCESS(2). Значит так: это описание системного вызова. Это мне не подходит... Смотрю секцию SEE ALSO и вижу команду chmod(2). В ней что-то есть такое.
# man 2 chmod
Здесь двойка указывает на то, что мануал берется из секции 2 – опять системный вызов, но делать нечего – кто ищет, тот всегда найдет. Тут уже становится интересней. Доступ к файлу - это то, что мне нужно: запретить доступ к моему мануалу нежелательным пользователям! Но что-то тут совсем уж заумно написано, идем в SEE ALSO и находим команду Chmod, только уже с индексом (1). Прекрасно. Посмотри мануал к ней и пойми, наконец, что это то, что тебе нужно. Оказывается, что доступ к файлу определяется четырехзначным числом x x x x. Первый разряд определяет специальные уровни доступа, о которых расскажу позже. Второй разряд - уровень доступа хозяина файла. Третий разряд - уровень доступа для группы пользователей. Четвертый – для всех остальных. Итак, теперь ты можешь узнать, как именно определяется доступ для них. Используется очень простая и в то же время удачная система. Есть три возможности для файла (директория – это тот же файл, предназначенный для хранения других файлов) – чтение (r), запись (w), исполнение (x). Вроде бы все понятно, но вот "исполнение директории" звучит как-то странно. Так и есть: смысл бита x применительно к директории имеет другой смысл: при наличии бита x можно зайти в директорию и осуществлять в ней поиск файлов.
Вернусь к моей программе и к ее мануалу. Так уж мне хочется, чтобы мой мануал мог читать только root, но, тем не менее, мою программу разрабатываю не только я, но и мой знакомый (назовем его r1c). Я и r1c, не имея доступа root’а (на данный момент я его имею, но это ненадолго), хотим в процессе разработки модифицировать как саму программу, так и мануал к ней. Для этого root’у необходимо дать право на чтение, а меня и r1c объединить в группу (devel) и разрешить этой группе чтение и запись этого файла. Вот и все. Теперь же осталось реализовать то, что было задумано. Каждому биту (r, w ,x) присвоен числовой аналог. R = 4, W = 2, X = 1. Хозяином файла теперь будет root, ему нужно только чтение, у него будет доступ 4. А группе devel нужна модификация и чтение итого 4+2 = 6. А все остальные не должны иметь доступа к файлу, то есть 0.
Собираем все воедино: chmod 0460 <имя файла>. Это и есть результат чтения мануалов. Почему первый разряд равен нулю? О назначении этого разряда ты без труда узнаешь из мануала по команде chmod -это и будет твое домашнее задание. Иногда случается такое, что ты висишь на консоли, читаешь на досуге очередной мануал, а тут связь с сервером обрубается. Все бы ничего, но обычно это приводит с "висящим" процессам и незакрытой сессии, которая тоже зависает. В этом, конечно, нет ничего страшного, но может зависнуть и процесс ping –s 50000 www.ru, а это уже неприятно. Убей его. Допустим, из зависших процессов нужно убить именно ping. Находим его среди процессов и определяем его pid (Process IDentifier):
# ps ax|grep "ping"
69560 p1 S+ 0:00.01 ping -s 40000 www.ru
Число, находящееся в начале строки, и есть этот самый pid, в этом случае - 69560. Это уникальный идентификатор данного процесса. Зная его можно расправиться с самим процессом. Поскольку нужно убить процесс, то опять идем за помощью к мануалу:
# man kill
Это и есть мануал по kill(1). С помощью этой команды можно послать сигнал процессу. Оказывается, что сигналов много и каждый из них имеет свое назначение. Я рассмотрю лишь два наиболее часто используемых сигнала – это –HUP и –9. Не странно ли, что один сигнал отображается в числовом виде, а другой в символьном? У каждого числового сигнала есть символьный аналог для удобства запоминания. Например –1 это –HUP, а –9 это –KILL. Итак, все-таки процесс убить придется. Его pid уже неизвестен, из man видим синтаксис, поэтому:
# kill –9 69560
Я выбрал –9, потому что мне нужно обязательно завершить этот процесс, а сигнал –KILL не может быть отловлен и проигнорирован. На самом деле сигнал –HUP должен интересовать тебя больше, чем даже –9. Допустим, у нас запущен прокси squid на сервере и что-то изменено в конфигурационном файле, но работающая программа об этом ничего не знает. Не будет же она постоянно перечитывать конфигурационный файл отслеживая изменения. Можно, конечно, убить процесс и запустить squid снова, но это ниже твоего достоинства. Лучше подать процессу сигнал о том, что конфигурационный файл изменился и что его нужно прочитать. Делается это опять же просто:
# kill –HUP pid
где pid – это идентификатор процесса, которому нужно подать сигнал. Конечно, идентификаторы - это хорошо, но не каждый человек способен сходу запомнить пятизначное число. Нужно посмотреть в таблицу процессов, найти нужный pid, скопировать или вписать его снова на консоль. Это долго, да и не всегда удобно. Тебя ждут более важные дела, а для свободы твоей гениальности придумана команда killall. Все то, что было сотворено с ping, можно было сделать проще:
# killall –9 ping
И даже не нужно было бы смотреть список процессов. Эта команда убьет все процессы ping, что не всегда желательно. Если вдруг на другой консоли сидит какой-то человек, например, мой знакомый по имени r1c, и кого-то пингует, то убийству своего собственного процесса он не порадуется. Это мокрое дело произойдет тогда, когда мы с ним будем работать от имени одного пользователя или когда я буду работать под root’ом. В том случае, если я не root и пытаюсь послать сигнал не моему процессу, мне просто будет отказано в доступе. А что сделать, чтобы не разозлить r1c’а? У команды killall есть два замечательных параметра –u и –t. Параметр –u ограничивает процессы, которым будет послан сигнал, по пользователю. То есть нужно написать:
# killall –u root –9 ping
И теперь будут убиты все процессы ping, которые запущены от имени root’а. Второй параметр может понадобиться, если захочешь поиздеваться над каким-либо пользователем. –t ограничивает процессы по терминалу. Что это значит и как это нам поможет? Используя команду
# w
можно добраться до списка пользователей, которые работают в системе на данный момент. Итак, мы видим колонку TTY. Это и есть имя терминала, за которым работает пользователь (терминал может быть как виртуальный, так и физический; в этом случае неважно). Подмечаем, что товарищ r1c работает за терминалом p2. Выполнив команду
# killall –t p2 –9 bash
сбрасываем r1c’а с консоли (при условии, что default-шелл у r1c’а именно bash).
Файловая система
Теперь о структуре файловой системы в *nix. Можно не знать, как посылать сигналы процессам, как читать мануалы, но вот без знания устройства файловой системы, а точнее устройства каталогов, просто нельзя жить. В основе файловой системы лежит каталог с именем "/". Его называют "корневым" каталогом: он занимает самый верхний уровень в иерархии файловой системы. В нем живут все остальные каталоги системы. Итак, сделаем
# ls /
и по порядку посмотрим, для чего нужна каждая папка.
/bin – здесь хранятся фундаментальные, основные пользовательские утилиты.
/boot – здесь хранятся программы и файлы, необходимые для загрузки системы.
/dev – здесь хранятся файлы устройств (например, замечательное псевдоустройство Urandom).
/etc – в этом каталоге можно увидеть конфигурационные файлы и скрипты. По сути, это место скопления конфигурационных файлов. Стоит особо отметить файл rc.conf, в котором определяется начальная настройка системы при загрузке.
/home – место, где обычно хранятся домашние директории пользователей (в FreeBSD 5.x это уже /usr/home), за исключением суперпользователя.
/mnt – эта папка обычно пуста, используется же она обычно как временная точка монтирования разделов.
/proc – полностью виртуальная файловая система.
/root – эта директория является домашней для пользователя root.
/sbin – здесь хранятся системные программы и утилиты администрирования.
/tmp – директория для хранения временных файлов. Не стоит доверять ей ценную информацию, потому что чаще всего администратор настраивает систему таким образом, что эта папка очищается при следующей загрузке.
/usr – основное хранилище для пользовательских утилит и программ. Тут-то и стоит искать вновь установленные программы и конфигурационные файлы к ним.
/var – здесь чаще всего хранятся логи, некоторые временные файлы, каталоги спулинга для электронной почты и принтеров и дополнительные файлы подкачки.
Это и есть основные каталоги в корневом каталоге. Также стоит отметить, что в каждом каталоге есть ссылка на каталог, который стоит выше по уровню. Эта ссылка имеет название "..". То есть чтобы перейти в папку, которая находится выше, пишешь
# cd ..
и попадаешь в директорию выше (или если ты в корневой директории - останешься в ней). Таким образом, произошло перемещение из /usr/local/etc в /usr/local.
Я попытался вложить в эту статью максимум информации, но еще больше осталось за кадром. Для того чтобы хорошо разбираться в *nix и понимать что к чему, существует лишь один рецепт успеха – истинно спецовская тяга к знанию и много-много часов, пожертвованных на чтение мануалов. Дерзай!