$ who | 2
drh tty0 Sep 28 21:23 cvw tty5 Sep 28 21:09
dmr tty6 Sep 28 21:10 scj tty7 Sep 28 22:11
you tty9 Sep 28 23:00 jib ttyb Sep 28 19:58
$
Реализация команд
2
,
3
, … идентична. По существу, они являются связями с одним файлом:
$ ln 2 3; ln 2 4; ln 2 5; ln 2 6
$ ls -l [1-9]
167222 -rwxrwxrwx 5 you 51 Sep 28 23:21 2
167222 -rwxrwxrwx 5 you 51 Sep 28 23:21 3
167222 -rwxrwxrwx 5 you 51 Sep 28 23:21 4
167222 -rwxrwxrwx 5 you 51 Sep 28 23:21 5
167222 -rwxrwxrwx 5 you 51 Sep 28 23:21 6
$ ls /usr/you/bin | 5
2 3 4 411 5
6 cx lc m nu
what where
$ cat 5
# 2, 3, ...: печать в n столбцов
pr -$0 -t -11 $*
$
Флаг
-t
убирает заголовки в начале страницы, а флаг
-ln
устанавливает размер страницы равным
n
строк. Имя программы становится числом столбцов, т.е. аргументов для команды pr, так что выходной поток печатается строками по несколько столбцов, число которых определено аргументом
$0
.
3.5 Результат выполнения программы в качестве аргумента
Теперь перейдем от аргументов команд для командного файла к порождению аргументов. Конечно, расширение имен файлов с помощью метасимволов, подобных
*
, является наиболее типичным способом порождения аргументов (иным, чем их явное задание), но столь же хорошим способом представляется и выполнение программы. Результат выполнения любой программы можно использовать в командной строке, заключив ее вызов в символы слабого ударения
`...`
:
$ echo At the tone the time will be `date`.
At the tone the time will be Thu Sep 29 00:02:15 EDT 1983.
$
Небольшое изменение показывает, что
`...`
интерпретируется и внутри кавычек
"..."
:
$ echo "At the tone
> the time will be `date`."
At the tone
the time will be Thu Sep 29 00:03:07 EDT 1983.
$
В качестве другого примера предположим, что вам необходимо послать почту группе людей, которые зарегистрированы под именем, хранящимся в файле
mailinglist
. Можно, конечно, отредактировать файл
mailinglist
так, чтобы он стал пригодным для применения команды
mail
и передать его интерпретатору, но значительно проще использовать команду
$ mail `cat mailinglist` <letter
Запуск команды
cat
порождает список имен пользователей, и эти имена становятся аргументами команды
mail
. (При обработке результата выполнения команды, помещенной между знаками слабого ударения и используемой в качестве аргумента, интерпретатор считает символы перевода строки разделителями слов, а не символами завершения командной строки; подробнее данный вопрос обсуждается в гл. 5.) Работать со знаками слабого ударения нетрудно, и поэтому, действительно, нет нужды вводить отдельный флаг команды
mail
, задающий список адресатов.
Несколько иной подход требуется для преобразования файла
mailinglist
из простого списка имен в программу, выдающую список имен:
$ cat mailinglist
echo don whr ejs mb
Новая версия
$ cx mailinglist
$ mailinglist
don whr ejs mb
$
Теперь посылка писем адресатам из списка реализуется командой:
$ mail `mailinglist` <letter
Добавив еще одну программу, получим возможность даже изменять список пользователей в диалоге. Такая программа называется
pick
:
$ pick аргументы...
и выдает свои аргументы по одному, ожидая каждый раз ответа. Результатом действия команды
pick
являются те аргументы, на которые был дан ответ
y
(
yes
— да); при всяком другом ответе аргумент отбрасывается. Например,
$ pr `pick *.с` | lpr
Здесь вначале выдаются имена файлов, оканчивающиеся на
.с
. Выбранные имена печатаются с помощью команд
pr
и
lpr
. (Команда
pick
не входит в состав команд седьмой версии, но она столь проста и полезна, что мы включили ее варианты в гл. 5 и 6).
Допустим, вы используете второй вариант команды
mailinglist
. Тогда посылка писем адресатам
don
и
mb
выглядит так:
$ mail `pick \`mailinglist\`` <letter
don? y
whr?
ejs?
mb? y
$
Обратите внимание на вложенные знаки слабого ударения; обратная дробная черта запрещает обработку вложенной конструкции
`...`
при разборе внешних знаков слабого ударения.
Упражнение 3.10
Что произойдет, если опустить символы обратной дробной черты в команде
$ echo `echo \`date\``
Упражнение 3.11
Попробуйте ввести
$`date`
и объясните результат.
Упражнение 3.12
Команда
$ grep -l pattern filenames
перечисляет имена файлов, которые соответствуют шаблону, но больше ничего не выдает. Попытайтесь выполнить разные вариации такого задания:
$ command `grep -l pattern filenames`