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
Это идентичный запуск, хотя и менее очевидный.
В чем состоит различие между следующими командами?
$ cat file | pr
$ pr <file
$ pr file
(С течением времени операция переключения < потеряла свою связь с программными каналами; "cat file |" считается более естественным, чем "< file".)
3.2 Метасимволы
Интерпретатор распознает еще ряд символов как специальные. Наиболее часто используется звездочка *, указывающая, что нужно искать в каталоге имена файлов, у которых вместо * может быть любая последовательность символов. Например,
$ echo *
есть не что иное, как некое подобие команды ls. В гл. 1 мы не отметили, что во избежание проблем с именами '.' и '..', которые присутствуют в любом каталоге, символы подстановки в именах файлов нельзя применять к именам файлов, начинающимся с точки. Правило таково: символы подстановки в именах файлов действуют на имена файлов, начинающихся с точки, только в том случае, если точка явно задана в шаблоне. Как обычно, "рассудительная" команда echo прояснит ситуацию:
$ ls
.profile
junk
temp
$ echo *
junk temp
$ echo .*
. .. .profile
$
Символы со специальным значением, подобные *, называются метасимволами. Существует множество метасимволов (в табл. 3.1 приводится их полный список, но некоторые символы мы обсудим только в гл. 5).
> |
prog > file — переключить стандартный выходной поток в файл |
>> |
prog >> file — добавить стандартный выходной поток к файлу |
< |
prog < file — извлечь стандартней выходной поток из файла |
| |
p1 | p2 — передать стандартный выходной поток p1 как стандартный выходной поток для p2 |
<<str |
"Документ здесь": стандартный выходной поток задается в последующих строках до строки, состоящей из одного символа str |
* |
Задает любую строку, состоящую из нуля или более символов, в имени файла |
? |
Задает любой символ в имени файла |
[ccc] |
Задает любой символ из [ccc] в имени файла (допустимы диапазоны, такие, как 0-9 или a-z) |
; |
Завершает команды: p1; p2 — выполнить p1, затем p2 |
& |
Выполняет аналогичные функции, но не ждет окончания p1 |
`...` |
Инициирует выполнение команд(ы) в ...; `...` заменяется своим стандартным выводом |
(...) |
Инициирует выполнение команд(ы) в ... в порожденном shell |
{...} |
Инициирует выполнение команд(ы) в ... в текущем вызове shell (используется редко) |
$1, $2, ... |
Заменяются аргументами командного файла |
$var |
Значение переменной var в программе на языке shell |
${var} |
Значение var; исключает коллизии в случае конкатенации переменной с последующим текстом (см. также табл. 5.3) |
\ |
\c — использовать непосредственно символ c, \ перевод строки отбрасывается |
'...' |
Означает непосредственное использование |
"..." |
Означает непосредственное использование, но после того, как $, `...` и \ будут интерпретированы |
# |
В начале слова означает, что вся остальная строка рассматривается как комментарий (но не в седьмой версии) |
var=value |
Присваивает value переменной var |
p1 && p2 |
Предписывает выполнить p1; в случае успеха выполнить p2 |
p1 || p2 |
Предписывает выполнить p1; в случае неудачи выполнить p2 |