Терминал был чуть ли не первым камнем преткновения, когда мы составляли список сущностей, которые составляют из себя линукс.
Интерфейс командной строки является наиболее старым, и, поэтому, многие вещи, которые существуют в POSIX-системах, лучше всего иллюстрируются через командную строку.
При попытке сделать домашнее задание выясняется, что в командной строке есть одно узкое место. Есть хороший задел на свойства оболочки -- команда в командной строке может быть просто программой,и мы можем настраивать систему достаточно гибким образом, используя интерпретатор, как связующий элемент. Но, когда новичкам говорят "работайте в командной строке", они обычно спрашивают: "Сколько команд в командной строке? Покажите мне список!"
Этот список очень велик и не является инвариантом. Какие программы установлены в системе, такой он и будет. Даже подмножество POSIX-команд настолько велико, что выучить все коммнады со всеми вариантами невозможно. Работая с командной строкой не надо всё заучивать, надо использовать справочные материалы. В процессе изучения справочных материалов вы могли бы прийти к достаточно забавному выводу: как костяк, так и основные утилиты, которые используются в сценариях, -- это либо утилиты работающие с файлами, либо утилиты обработки текста, либо утилиты работы с процессами. С процессами меньше, чем с файлами и текстами. Понятия файл и текст достаточно корневые и инвариантные. Когда мы будем рассматривать конфигурационные файлы системы, мы увидим, что это файлы в текстовом формате. Работа с системой -- это работа с файлами и с текстами, в них содержащимися.
Файловая система
Напомню, что наша задача -- не изучение жесткого стандарта (fhs), а рассказ о том, что надо знать, чтобы пользоваться линуксом. Первое -- представление о том, как файлы и каталоги называются, и как к ним обращаться.
Существует корень, из которого растут все остальные каталоги. Единое дерево. Чтобы добраться до определенного файла (/usr/bin/passed) необходимо написать полный путь. Поскольку в линуксе одно дерево, такого указания будет всегда достаточно, именно поэтому такой путь называется полным.
Встает вопрос -- а что делать, если файловых систем много? Они на разных дисках? В случае виндоуса есть разные буквы. В случае линукса такие разделы должн быть "смонтированы", то есть включены в общее дерево файловой системы. Например /home может быть на отдельном разделе, но он подключен к mount-point /home. Монтируется суперпользователем, командой mount.
С помощью операции монтирования естественным образом все различные файловые системы могут быть объединены в единое дерево каталогов, и принцип доступа к файлу по его пути не нарушается.
mount что куда
Пользователь этим чаще всего не занимается.
FHS описывает какие файлы где лежат. Несколько выдержек:
/bin -- лежат программы
/sbin -- программы, которые вам не нужны. Всякие демоны, которые не вызывают обычные пользователи, работа с сетью, тот же mount.
/lib -- разделяемые библиотеки, которые нужны для работы программам.
/mnt, /media -- в них заводятся маунтпойнты. В /media монтируется автоматически. Безопасно извлечь нажали -- оттуда оно отмонтируется и удаляет каталог. Если же вы захотели по быстрому смонтировать образ какой-то исошки пальцами, вы сами создаете каталог в /mnt.
/dev
/proc
/sys
Последние три -- виртуальные фс. /sys представляет в виде фс аппаратный профиль вашего компьютера. Идея в том, что вы работаете обычным файловым api, а на самом деле работаете с аппаратной составляющей. В /proc информация о процессах, в линуксах он очень-очень развесистый. Вы можете перезагрузить компьютер, отправив последовательность букв в файл. Манипуляция файлами в виртуальной фс приводит к тому, что вы управляете системой, не выходя из парадигмы файл-текст.
Довольно примечателен тот факт, что в фс обязательно есть каталог /usr, в котором опять обнаружим /usr/bin, /usr/sbin, /usr/lib. Считается, что то, что расположено в каталогах первого уровня, позволяет эту систему починить, в случае чего.
Если мы вынесем /usr и /home в отдельные разделы, то сам корень у нас будет фиксированного размера, а всё растущее будет отдельно.
Каталог /usr/share был актуален раньше. Допустим, мы эксплуатируем разные платформы в рамках одной сети. В /usr/share лежат платформонезависимые вещи. Сценарии, модули к питону или перлу, документация. Бинариники, очевидно, платформозависимы. Было это сделано для того, чтобы накидать скрипты и прочее на один файловый сервер, и потом подгружать на разные машины. Правда, сейчас так уже никто не делает. Но в /usr и сейчас лежат небинарники.
Далее идет каталог /usr/local. И в нём мы опять видим bin, lib, etc ... По fhs содержимое /usr/local должно переживать переустановку системы. Если вы накатали наколенный скрипт, то лучшее место для него -- /usr/local/bin. Если вы задумаете переустановить систему, то оно трогаться не будет, если вы задумаете всё убить, то хотя бы будете четко знать, что бэкапить, а не выискивать среди тысяч других программ и скриптов свои родные.
Для той же цели служит /opt . Всякая ерунда, которую непонятно куда ставить. Важное отличие от /usr/local -- /usr/local} структурирован. При установке в него все раскладывается по папочкам. В /opt делается одна папка на приложение и в ней всё.
Ещё идея, что /usr/local специфичен для данного хоста, а в /opt кидается всё, несоответствующее FHS.
Тут возникло слово /etc, о нём надо поговорить отдельно. В нём хранятся настройки. Возможно в этом, возможно в следующем семестре, мы немножко посмотрим структуру самого /etc. Если мы хотим по-быстрому сохранить при переустановке нашу систему, то должно быть достаточно сохранить /etc, /home, /usr/local, /opt.
В /etc большинство конфигов в человекочитаемом текстовом формате. Пожалуй, все, кроме gconf. Название /etc -- как будто там не нужное, а, на самом деле, там всё самое нужное лежит. Если хотим понять как работает система, нужно смотреть в /etc.
Приближаемся к ещё одному инварианту -- правам доступа. Есть некоторые каталоги, в которые вам даже посмотреть нельзя. Например, /root. Есть обратное -- /tmp, который доступен на запись всем пользователям. Это специальный каталог для хранения временных файлов. Ещё один каталог, /home. В нём есть подкаталоги, которые являются домашними директориям пользователей. В свой подкаталог пользователь может записывать, и при старте приложения этот каталог является текущим (????). Права достцпа к подкаталогам /home более мягкие, чем ко всем остальным.
Ещё один важный каталог /var. Используется для хранения данных переменного размера -- системных журналов, итп. Например, /var/log . Свойство каталога /var -- содеражть файлы очень разного размера -- является поводом хранить /var в отдельной фс. Файлы в /var ведут себя совершенно особенно. Вдруг у вас на сервере что-то станет глючить каждую 0.1 секунды и выдавать сообщения об ошибках. Вы вернетесь через неделю, а у вас места нет вообще нигде. А переполнение корня -- это не лучшая вещь. А если переполняются только системные журналы, то это менее страшно.
В /tmp разные пользователи и приложения имеют дурную привычку хранить всякий мусор.
В /var/lib хранятся изолированные окружения. Имейте в виду, что, в некоторых случаях, придется лезть туда (для поиска настроек того же неймсервера).
Такая структура каталогов -- достаточно строгий инвариант, на тех кто его нарушает показывают пальцем.
В /boot лежат ядро, конфиги загрузчика и прочие необходимые ему вещи. /boot тоже часть fhs.
Теперь самое правильное было бы заняться правами доступа, но есь ещё одна тема, которую надо потрогать, н не заглубляться в неё слишком. Эта тема процессы.
Процессы
Говоря про процессы, я введу несколько обозначений, которые будут агрессивно использоваться в следующий раз.
В операционной системе может быть сколько угодно процессов, "сколько угодно" -- это число. Никакого параллелизма в смысле четкого параллелизма не существует, ядер у нас штуки две, плюс-минус, и в каждй момент у нас может работать одновременно только две задачи. Подробности -- в курсе архитектура ЭВМ.
У процесса есть идентификатор -- PID. Идентификатор процесса у всех процессов уникальный. У каждого процесса есть PID. Ещё у него есть идентификатор пользователся, который его запустил, под которым он работает. Ещё идентификатор группы.
У каждого запущенного процесса существует окружение. Список открытых файлов, переменные окружения, ещё много чего.
Когда мы хотим породить дочерний процесс, это происходит в два этапа.
fork делает два не абсолютно одинаковых процесса. Из разного у них только PID. Мы получаем полностью идентичное окружение -- открытые файлы, идентификаторы пользователя и группы, итд. На основании того, кому функция fork вернула ноль, а кому идентификатор дочернего процесса, эти процессы делают вывод о том, кто их них дочерний, кто из них родительский. Потом дочерний процесс обычно делает exec. При этом заменяется выполняемый процессом код.
Без особых на то прав процесс не может сам взять и поменять себе идентификатор пользователя или идентификатор группы. Процесс, запущенный с правами пользователя и группы, никогда (на сегодняшние наши знания) не сможет породить процесс с другими правами. Это дает нам возможность породить систему определения, имеет ли права процесс на работу с таким то файлом, или нет.
Вернёмся к нашим процессам.
Запуск в фоне
ls & ls & ls
Она запускается в фоне и работает пока не закончится, при этом можно делать что-нибудь ещё.
Итак, у нас три параллельно работающих ls. Увидим смесь выдачи.
А что будет, если программа в фоне захочет вводить? В линуксах простое правило. С терминалом связан по вводу только один процесс. Если фоноые хотят вводить, их приостанвят. Об этом подробнее потом.
Итак процессы можно запускать в фоне, но они не могут вводить со стандартного ввода.
Процесс может получать сигналы. Их может посылать процесс или ос. Доставка сигнала -- дело ос, если процесс не полчил сигнал, это значит что уже всё, ядро не фурычит. Например процесс пытается считать дискету, жуёт её жуёт, уже и такой сигнал послал ему, и сякой, а он всё фурчит. Это означает, что он застрял, там, в ядре.
Сигналы послыаются командочкой kill.
Процессы могут общаться сигналами достаточно эффективно.
Есть сигналы, которые убивают процесс.
Есть сигналы которые говорят, что что-то случилось с ос.
ДЗ. Найти пример стандартной линукс программы, обрабатывающей сигнал SIGUSR1. И надо рассказать как и зачем она это делает.
Для удобства работы шелл предоставляет возможность посылать сигналы с клавиатуры. Но только активному процессу( не фоновому).
Резюме -- управление процессами происходит с помощью сигналов, шелл предоставляет возможность их посылать.
В следующий раз права доступа и альтернативные способы межпроцессного взаимодействия -- dbus.