Главная » Программирование для UNIX » Работа  с оболочкой Структура командной строки

0

Самой  важной программой для большинства пользователей UNIX  является оболочка – программа, которая интерпретирует запросы на исполнение  команд;  взаимодействие с  ней  занимает  больше времени, чем со всеми  другими программами, может быть, за исключением любимого   текстового  редактора. В  этой  главе и  в  главе 5  представлен большой  объем  информации,  касающейся  возможностей  оболочки. Это сделано для того,  чтобы показать, что очень  многие задачи можно решить, не прилагая титанических усилий и, конечно же, не прибегая к программированию на традиционных языках типа  Си.

Мы разделили рассказ об оболочке на две главы. Данная глава описывает  более  сложные, чем  описанные в главе 1, но  также широко используемые свойства  оболочки: применение метасимволов,  заключение в кавычки, создание новых команд, передача им аргументов, работу с переменными оболочки и элементарные управляющие конструкции. Это то, что следует знать для того, чтобы самостоятельно использовать оболочку. Материал же, представленный в главе 5, несколько сложнее –  он предназначен  для  написания серьезных программ оболочки, «пуленепробиваемых» для  других  пользователей.  Информация  поделена между главами в некоторой  степени случайным образом, так что в конечном счете надо прочесть обе.

Начнем с того, что попробуем понять, что такое команда и как она интерпретируется оболочкой. В этом  разделе  не очень  много  новой  информации, основная часть  посвящена  формализации базовых сведений, представленных в главе 1.

Простейшая команда состоит  из одного слова, обычно  этим  словом  является имя   файла,  который  должен  быть   выполнен  (позже  будут рассмотрены и другие виды  программ):

$ who                                      Исполнить файл /bin/who you           tty2        Sep 28  07:51

jpl        tty4        Sep 28 08:32

$

Обычно команда заканчивается символом разделителя строк, но часто  для завершения команды применяется и точка с запятой ;:

$ date;

Wed  Sep 28 09:07:15  EDT  1983

$ date;  who

Wed  Sep 28 09:07:23  EDT  1983

you

tty2

Sep 28 07:51

jpl

tty4

Sep 28 08:32

$

Несмотря на то что для завершения команды можно использовать точку с запятой, обычно ничего не происходит до тех пор,  пока  не нажата клавиша Return. Обратите внимание на то,  что после  нескольких команд, введенных в одной строке, оболочка выводит только одно  приглашение на  ввод,  но  в остальном (не  считая  количества приглашений) ввод

$ date;  who

идентичен вводу  двух  команд в разных  строках.  В частности, who не выполняется до тех пор, пока  не завершится date.

Попытаемся передать вывод «date;  who» в канал:

$ date;  who | wc

Wed  Sep 28 09:08:48  EDT  1983

2                                                                10         60

$

Вероятно, это не совсем то, чего вы ожидали. Дело в том, что только вывод who передается wc. Соединение команд who и wc посредством канала образует единую команду, которая называется  конвейером (pipeline), она-то  и выполняется после  завершения date. При  разборе командной строки оболочка учитывает то, что приоритет | выше, чем приоритет ;.

Можно  сгруппировать команды при помощи скобок:

$ (date; who)

Wed  Sep  28  09:11:09  EDT  1983 you           tty2        Sep  28  07:51 jpl           tty4        Sep  28  08:32

$ (date; who)  | wc

3                                                                16         89

$

Результат выполнения команд date  и who конкатенируется в один  поток, который может быть направлен в канал.

Поток данных по каналу может быть перехвачен и помещен в файл (но не в другой канал) с помощью команды tee, которая не входит в оболоч ку,  но может быть полезна для  работы с каналами. Одно из ее возможных применений – это сохранение промежуточного вывода в файле:

$ (date; who)  | tee  save  | wc

3         16         89                                   Вывод из  wc

$ cat  save

Wed  Sep  28  09:13:22  EDT  1983 you           tty2        Sep  28  07:51 jpl           tty4        Sep  28  08:32

$ wc <save

3         16         89

$

Команда tee копирует свой ввод в указанный файл или файлы, а также в свой  вывод, так  что wc получает те же  входные данные, которые бы она получила, если бы tee не входила в конвейер.

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

$ long-running-command  &      Команда с большим временем исполнения

$                                               Приглашение на ввод появляется сразу же

Можно и  более  интересно использовать  фоновые процессы, если  задействовать  возможность группировки команд. Команда  sleep ждет указанное количество секунд, прежде чем завершиться:

$ sleep 5

$                                                            Приглашение появляется через 5 секунд

$ (sleep 5;  date) &   date

5278

Wed  Sep 28 09:18:20  EDT  1983O      Вывод второй команды date

$ Wed  Sep 28 09:18:25  EDT  1983     Приглашение, через 5 секунд date

Фоновый процесс запускается и сразу  же засыпает; тем временем вторая  команда date печатает текущее время, и оболочка выдает приглашение на ввод новой  команды. Через пять секунд sleep завершается, и первая команда date печатает новое время. Тяжело объяснить течение времени на бумаге, так  что лучше попробуйте запустить этот  пример на компьютере. (В зависимости от загруженности компьютера и неко-

торых других причин, промежуток времени между двумя событиями может составлять не ровно пять секунд.) Таким образом, не составляет труда запустить команду в  будущем;  можно, например, реализовать удобное напоминание

$ (sleep 300;  echo Tea is ready)  &   Чай будет  готов через 5 минут

5291

$

(Если  в строке, которая должна быть  отражена на терминале, присутствует ctl-g, то при выводе раздастся звуковой сигнал.) Использование скобок в этих  примерах необходимо, поскольку приоритет амперсанда выше, чем у точки с запятой.

Амперсанд как указатель конца применяется к командам, а так  как конвейер – это команда, то для запуска конвейера в фоновом режиме наличие скобок в записи не требуется:

$ pr  file | lpr  &

Файл выводится на принтер, но это не заставляет вас ожидать завершения команды. Если заключить конвейер в скобки, эффект будет тем же самым, но придется вводить больше текста с клавиатуры:

$ (pr  file | lpr) &                  Аналогично предыдущему примеру

Большинство программ принимают в  командной  строке аргументы, как file  (аргумент pr)  в последнем примере. Аргументы –  это  слова, разделенные пробелами и знаками  табуляции, обычно  представляющие  собой  имена файлов для  обработки, но,  будучи  строками, могут  быть  интерпретированы программой любым подходящим для  нее способом. Например, pr принимает имена файлов для печати, echo отражает свои аргументы на терминал без интерпретации, а первый аргумент grep  задает текстовый шаблон, который  должен  использоваться при  поиске. И,  конечно  же, многие программы также имеют  параметры, которые указываются аргументами, начинающимися со знака минус.

Различные специальные символы, интерпретируемые  оболочкой (такие, как <,  >,  |,  ; и  &),  не  являются аргументами  запускаемых программ. Вместо этого они контролируют то, как оболочка их запускает. Например,

$ echo Hello  >junk

Здесь сообщается, что оболочка должна запустить echo с единственным аргументом Hello и поместить вывод  в файл junk. Строка >junk не является аргументом команды echo; она интерпретируется оболочкой, и ec– ho ее даже не видит. На самом  деле  эта строка не обязательно должна быть последней в команде:

$ >junk echo Hello

В этом случае происходит то же самое, но такая запись менее очевидна.

Упражнение 3.1. В чем отличия трех команд, приведенных ниже?

$ cat  file | pr

$ pr  <file

$ pr  file

(С годами оператор перенаправления < уступил в популярности каналам, похоже, конструкция cat   file  | кажется людям более естественной,  чем <file.) ~

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии