
К9-12В. Вопросы и ответы к ГОСам 2013 / Операционные системы / 04. Способы группирования команд в ОС. Командные файлы. Программные каналы, конвейеры команд
.docx04. Способы группирования команд в ОС. Командные файлы. Программные каналы, конвейеры команд
В операционных системах команды можно разделить на несколько основных групп:
• команды для работы с деревом каталогов (ls, cd, pwd, mkdir -p, rmdir, tree – вывод дерева каталогов);
• команды для работы с файлами (mv, cp, touch, cat, more, ln, find);
• команды ввода/вывода;
• информационные команды (bdf, top, whoami);
• команды управления правами доступа (chmod, chgrp, chown, umask).
Для хранения и выполнения последовательности команд используются командные
файлы (shell-процедуры). Shell- процедура – это обычный файл, содержащий команды системы UNIX, а также дополнительные команды, позволяющие программисту создавать ветвящиеся участки и циклы.
|
|
Для выполнения
shell - процедуры необходимо иметь право
доступа к этому файлу на
чтение и выполнение. Для обращения к shell - процедуре из командной строки
необходимо ввести имя shell - процедуры и ряд параметров, если это необходимо.
$ <имя shell - процедуры><параметр1>< параметр2>
Каждому аргумен ту, передаваемому в shell - процедуру из командной строки, ставится в
соответствие порядковый номер от 1 до 9. Если порядковый номер двузначный, то он
должен быть заключен в фигурные скобки {}. Имени процедуры ставится в соответствие
порядковый номер 0.
В shell данные могут передаваться одним из 3 -х способов:
1. через переменные среды;
2. через аргументы командной строки;
3. с помощью команды read .
Команда read <переменная> [переменная] в процедуре передает значения переменных во
время работы этой процедуры, причем вводимые пользователем значения будут
присваиваться указанным переменным.
Конвейер позволяет напрямую использовать вывод одной команды в качестве ввода
другой команды без использования промежуточного файла. Конвейер обозначается |.
<команда1> | < команда2> | < команда3>
Количество команд не ограничено. Самая первая команда в конвейере должна в
нормальном режиме выводить информацию в потока stdout . Самая последняя –
принимать информацию из потока stdin . Все промежуточные команды в конвейере
должны принимать информацию из стандартного потока ввода и передавать в
стандартный поток вывода. Такие команды называются фильтром.
Основной принцип работы программного канала состоит в буферизации байтового
вывода одного процесса и обеспечении возможности чтения содержимого программного
канала другим процессом в режиме FIFO (т.е. первым будет прочитан байт, который раньше всего записан).
Программным каналом называется использование вывода одной команды в качестве ввода для другой программы. Например:
$ dmesg | less
Команда dmesg выводит сообщения ядра Линукс о процессе загрузки ОС (те самые, что пробегают по экрану монитора при загрузке системы). Эти сообщения не умещаются на одном экране, и пролетают так быстро, что прочесть их невозможно. Поэтому вывод программы dmesg передают на ввод команде less. (Команда less позволяет выводу команды dmesg заполнить только один экран. Чтобы прочесть следующую порцию текста, нужно нажать клавишу пробела, а чтобы вернуться к предыдущей порции - клавишу b. Прервать работу программы можно клавишей q). Оператором такой передачи служит вертикальная черта (|). (Пробелы до и после вертикальной черты ставятся для удобства чтения, но можно обойтись и без них). Все вместе и есть простейший программный канал.
Того же результата можно достичь, если сначала перенаправить вывод команды dmesg во временный файл, а затем просмотреть содержимое этого файла на экране монитора.
$ dmesg > временный.файл
$ временный.файл > less
Очевидно, что такая схема менее производительна: во-первых, необходимо давать две команды, во-вторых потому, что следующая команда может начать работать только после завершения первой.
Английское название именованного канала - named pipe или FIFO (File In, File Out - файл пришел, файл ушел). Именованные каналы служат в основном для межпроцессного взаимодействия, когда различные процессы в системе обмениваются информацией. Тема это сложная и большая, заслуживающая отдельной статьи. Поэтому в данной работе я только вкратце коснусь ее.
В отличие от анонимного программного канала, автоматически создаваемого шеллом, именованный канал обладает именем, и создается явно при помощи команд mknod или mkfifo. Создадим именованный канал fifo1:
$ mkfifo fifo1
Теперь запустим процесс, обращающийся к данному каналу:
$ grep fs < fifo1 (ENTER)
Несмотря на нажатие клавиши ENTER ничего не происходит, что не удивительно, ведь файл fifo1 пока пуст, и команде grep нечего обрабатывать. Однако консоль оказывается занята ждущим процессом, и разблокировать ее можно только прервав процесс (скажем, нажатием клавиш CTRL+c).
Чтобы наполнить именной канал содержимым, нужно чтобы к нему обратился второй процесс. Для этого мы должны открыть вторую консоль и запустить какую-либо команду, передающую данные в файл fifo1. Например:
(Другая консоль)$ ls /etc > fifo1
Немедленно в первой консоли сработает команда grep:
$ grep fs < fifo1 (ENTER)
fstab
gettydefs
login.defs
mke2fs.conf
Совершенно ясно, что пользоваться таким неудобным механизмом в пользовательских целях никто не будет, ведь гораздо проще запустить один программный канал:
$ ls /etc | grep fs
и получить тот же результат.
Этот пример я привел лишь для демонстрации создания и работы именованного канала. Другое дело, когда именованные каналы создаются самими процессами для обмена информацией друг с другом.
Стандартный ввод - поток номер 0 (stdin) зарезервирован для чтения команд пользователя или входных данных.
Стандартный вывод - поток номер 1 (stdout) зарезервирован для вывода данных, как правило (хотя и не обязательно) текстовых.
Стандартный вывод ошибок - поток номер 2 (stderr) зарезервирован для вывода диагностических и отладочных сообщений в текстовом виде.