Чтение онлайн

ЖАНРЫ

UNIX — универсальная среда программирования
Шрифт:

$ date; who

идентичен вводу двух команд в разных строках. В частности, команда

who
не будет выполняться до завершения
date
. Попробуйте послать результат выполнения этих команд по программному каналу:

$ date; who | wc

Wed Sep 28 09: 08:48 EDT 1983

2 10 60

$

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

who
передается команде
wc
. При связывании
who
и
wc
через программный канал образуется единая команда, называемая конвейером, которая выполняется после
date
.
В процессе разбора командной строки
shell
считает приоритет операции
'|'
выше, чем операции
';'
. Для группирования команд следует использовать скобки:

$ (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
собрать и поместить в файл (но не в другой программный канал). Команда
tee
является частью интерпретатора
shell
, но тем не менее удобна и при манипулировании программными каналами. Ее можно использовать для сохранения промежуточного результата в файле:

$ (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 48

$

Команда

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

В качестве еще одного символа, завершающего команду, применяют амперсанд (

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

$ long-running-command &

5273
Номер процесса длительной команды

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

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

sleep
ожидает указанное число секунд, прежде чем закончить свое выполнение:

$ sleep 5

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

$ (sleep 5; date) & date

5278

Wed Sep 28 09:18:20 EDT 1983
Результат второй команды date

$ Wed Sep 28 09:18:25 EDT 1983
Появляется приглашение, затем

через 5 секунд дата

Фоновый процесс начинается, но сразу "засыпает"; тем временем вторая команда

date
выдает текущее время, а интерпретатор — приглашение для ввода новой команды. Пятью секундами позже прекращается выполнение команды
sleep
, и первая команда
date
выдает новое время. Трудно представить на бумаге истечение времени, поэтому вам следует попытаться самостоятельно реализовать этот пример. (Разница между двумя значениями времени может и не равняться в точности 5 с, в зависимости от загруженности машины и по ряду других причин.) Это удобный способ отложить запуск команды на будущее; рассмотрите также
в качестве удобного механизма такой пример:

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

5291

$

(Если в строке, следующей за командой

echo
, есть символ ctl-g, то при появлении ее на экране зазвонит звонок.) В этих примерах нужны скобки, так как приоритет
'&'
выше, чем у
';'
.

Символ

&
может завершать команды, а поскольку конвейеры являются командами, в скобках для запуска конвейеров как фоновых процессов нет необходимости, поэтому

$ pr файл | lpr &

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

$ (pr файл | lpr ) &
To же, что и в предыдущем примере

Большинство команд допускает наличие аргументов в командной строке, таких, как файл в предыдущем примере (аргумент команды

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

Различные специальные символы, интерпретируемые

shell
, такие, как
<
,
>
,
|
,
;
и
&
, не являются аргументами команд, запускаемых интерпретатором. Они управляют самим процессом запуска. Например,

$ echo Hello > junk

требует, чтобы интерпретатор запустил команду

echo
с одним аргументом
Hello
и поместил выходной поток в файл
junk
. Строка
> junk
не является аргументом команды
echo
; она интерпретируется
shell
, и
echo
никогда ее "не увидит". На самом деле, данная строка может и не быть последней в командной строке:

$ > junk echo Hello

Это идентичный запуск, хотя и менее очевидный.

Упражнение 3.1

В чем состоит различие между следующими командами?

$ cat file | pr

$ pr <file

$ pr file

(С течением времени операция переключения

<
потеряла свою связь с программными каналами; "
cat file |
" считается более естественным, чем "
< file
".)

3.2 Метасимволы

Интерпретатор распознает еще ряд символов как специальные. Наиболее часто используется звездочка

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

$ echo *

есть не что иное, как некое подобие команды

ls
. В гл. 1 мы не отметили, что во избежание проблем с именами
'.'
и
'..'
, которые присутствуют в любом каталоге, символы подстановки в именах файлов нельзя применять к именам файлов, начинающимся с точки. Правило таково: символы подстановки в именах файлов действуют на имена файлов, начинающихся с точки, только в том случае, если точка явно задана в шаблоне. Как обычно, "рассудительная" команда
echo
прояснит ситуацию:

Поделиться с друзьями: