Операционная система UNIX - Андрей Робачевский
Шрифт:
Интервал:
Закладка:
В табл. 1.9 приведен синтаксис перенаправления ввода/вывода, а на рис. 1.9 схематически показаны примеры перенаправления потоков.
Таблица 1.9. Перенаправление потоков ввода/вывода
>file Перенаправление стандартного потока вывода в файл file >>file Добавление в файл file данных из стандартного потока вывода <file Получение стандартного потока ввода из файла file p1 | p2 Передача стандартного потока вывода программы p1 в поток ввода p2 n>file Переключение потока вывода из файла с дескриптором n в файл file n>>file To же, но записи добавляются в файл file n>&m Слияние потоков с дескрипторами n и m <<str "Ввод здесь": используется стандартный поток ввода до подстроки str. При этом выполняются подстановки метасимволов командного интерпретатора <<str To же, но подстановки не выполняютсяРис. 1.9. Пример перенаправления стандартных потоков ввода/вывода
Рассмотрим несколько примеров перенаправления потоков.
Запуск некой программы ведения журнала можно выполнить следующим образом:
$ logger >> file.log
При этом вывод программы logger будет записываться в конец файла file.log, сохраняя все предыдущие записи. Если файла file.log не существует, он будет создан. В отличие от этого, использование символа '>' указывает, что сначала следует очистить файл, а затем производить запись.
Стандартным потокам ввода, вывода и вывода ошибок присваиваются дескрипторы — числовые значения, являющиеся указателями на соответствующий поток. Они, соответственно, равны 0, 1 и 2. Перенаправлять потоки можно, используя эти числовые значения. Таким образом, предыдущему примеру эквивалентна следующая запись:
$ logger 1>>file.log
Чаще всего числовое значение дескриптора потока используется для потока ошибок. Например, чтобы подавить вывод ошибок, можно использовать следующую запись:
$ run 2>/dev/null
где /dev/null является псевдоустройством, удаляющим все введенные в него символы.
Командный интерпретатор предоставляет возможность слияния потоков. Например, при запуске команды
$ run_long_program >/dev/null 2>&1 &
сообщения об ошибках будут также выводиться в файл /dev/null. Символ '&' перед именем потока необходим, чтобы отличить его от файла с именем 1. Заметим, что изменение порядка двух перенаправлений потоков приведет к тому, что сообщения об ошибках будут по-прежнему выводиться на экран. Дело в том, что Shell анализирует командную строку слева направо, таким образом сначала будет осуществлено слияние потоков и оба будут указывать на терминал пользователя, а затем стандартный поток вывода (1) будет перенаправлен в файл /dev/null.
Передача потока вывода одной программы в поток ввода другой осуществляется с помощью конвейера '|' (программного канала). Программные каналы часто используются для фильтрации вывода некоторой команды:
$ ps - ef | grep myproc
позволяет получить информацию о конкретном процессе myproc. Утилита ps(1) выводит на экран информацию обо всех процессах в системе, программа grep(1) фильтрует этот поток, оставляя лишь строки, в которых присутствует слово myproc.[14]
Можно усложнить задачу и попытаться получить идентификатор процесса myproc. Однако здесь нам не обойтись без других средств системы. В данном случае мы будем использовать интерпретатор awk(1):
$ ps -ef | grep myproc | awk '{ print $2 }'
Идея заключается в фильтрации второго поля записи о процессе myproc, содержащего идентификатор процесса (см. описание утилиты ps(1)).
Иногда возникает необходимость разместить поток ввода вместе с командой. Для этого используется выражение "ввод здесь". Проиллюстрируем его на примере:
$ at Dec 31 <<!
cat happy.new.year | elm -s"C Новым Годом"
[email protected]
!
По определению, команда at(1) устанавливает вызов команды, полученной ею со стандартного ввода (клавиатуры терминала), на определенное время (в данном случае — на 31 декабря каждого года). С помощью выражения "ввод здесь" мы явно задали вид этой команды, точнее комплекса команд: cat(1) передает текст поздравления программе elm(1), отвечающей за отправление сообщения электронной почты.
Команды, функции и программы
Все команды, которые вводятся в строке приглашения shell, относятся к одной из следующих категорий:
□ встроенные функции
□ функции shell, определенные пользователем
□ внешние программы и утилиты
Непосредственное отношение к shell имеют только первые две категории, а программы и утилиты являются обычными исполняемыми файлами.
Запуск встроенной функции не требует порождения нового процесса, поскольку эта функция реализована в самой программе shell (например, /bin/sh). Соответственно, встроенные функции shell выполняются быстрее всего. Рассмотрим важнейшие встроенные функции shell.
: Пустая команда. Код возврата всегда 0 (успех). Пустая команда удобна для создания бесконечных циклов, например: while : do ... done . runme Текущий командный интерпретатор выполняет команды, указанные в файле runme. При этом не происходит порождения нового shell, как в случае запуска на выполнение runme. Например, использование в скрипте команды . /usr/bin/include_script выполнит команды файла include_script, как если бы они являлись частью текущего скрипта. break [n] Производит выход из цикла for или while. Если параметр n указан, происходит выход из n вложенных циклов ps -ef | awk '{ print $1 " " $2}' | while read uid pid do if [$pid -eq $PID] then echo pid=$pid user=$uid break fi done cd [dir] Осуществляет переход в каталог dir. Если параметр не указан, происходит переход в домашний каталог ($HOME) echo [string] Строка string выводится на стандартное устройство вывода (терминал) exec runme Выполняет программу runme, заменяя ею текущий командный интерпретатор. Например, если в login shell (командном интерпретаторе, запускаемом при регистрации пользователя в системе) мы вызовем exec ls, то после вывода имен файлов текущего каталога произойдет завершение работы в системе exit [n] Завершает работу текущего интерпретатора (или скрипта) с кодом возврата n. По умолчанию код возврат равен 0 export [name1], [name2...] Помещает переменные, указанные в качестве аргументов, в окружение текущего shell, делая их тем самым экспортируемыми, т.е. доступными для запускаемых из интерпретатора программ hash [-r] [command, command...] Для каждой команды, указанной в качестве аргумента, запоминается полный путь. Таким образом, при последующих вызовах этих команд поиск не производится. Ключ -r удаляет все ранее запомненные пути. Если команда hash вызвана без аргументов, то выводится информация о запомненных путях jobs Если командный интерпретатор поддерживает управление заданиями, данная команда выводит список текущих заданий. См. раздел «Система управления заданиями», далее в этой главе kill [-sig] pid1 pid2... Посылает сигнал, определённый параметром sig, процессам, указанным параметрами pid. Параметр pid может быть либо идентификатором процесса, либо идентификатором задания, если поддерживается управление заданиями (в этом случае идентификатор должен предваряться символом '%' в соответствии синтаксисом системы управления заданиями). См. раздел «Система управления заданиями далее в этой главе pwd Выводит имя текущего каталога read var1 var2 ... Построчно считывает слова (т.е. группы символов, разделённые пробелами) из стандартного потока ввода, последовательно присваивая переменным var, указанным в качестве параметров значения, равные считанным словам. Если число слов в строке превышает число переменных, то последней переменной присваивается значение, равное остатку строки return [n] Осуществляет выход из функции с кодом возврата n. По умолчанию возвращается код последней команды set При задании без параметров выводит список определённых переменных shift [n] Производит сдвиг позиционных параметров, хранящихся в $1, $2 и т.д. на n позиций. По умолчанию сдвиг производится на одну позицию test Вычисляет условное выражение. Возвращает значение 0 — истина, или 1 — ложно. См раздел условные выражения далее в этой главе times Выводит суммарное время использования процессора программами, запущенными из текущего командного интерпретатора trap command sig1 sig2 ... Определяет команду command, которая будет выполнена при получении сигналов, указанных в качестве аргументов sig. См. раздел "Сигналы" ранее в этой главе type name Показывает, как name будет интерпретироваться командным интерпретатором ulimit Выводит или устанавливает значение пределов, ограничивающих использование задачей системных ресурсов (времени процессора, памяти, дискового пространства). Ограничения будут рассматриваться в главе 2 umask nnn Устанавливает маску прав доступа для вновь создаваемых файлов равной nnn unset var1 var2 ... Удаляет переменные, указанные в качестве аргументов, из списка определенных переменных командного интерпретатора. Некоторые переменные, например PATH, PS1, PS2, не могут быть удалены wait pid Ожидает завершения выполнения процесса с идентификатором pid и возвращает его код возвратаПользователь может определить функцию командного интерпретатора и использовать ее как встроенную функцию shell. С другой стороны, функции мало отличаются от скриптов, включая синтаксис и передачу аргументов. Однако являясь частью shell, функции работают быстрее.