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`
Запуск команды
cat
порождает список имен пользователей, и эти имена становятся аргументами команды mail
. (При обработке результата выполнения команды, помещенной между знаками слабого ударения и используемой в качестве аргумента, интерпретатор считает символы перевода строки разделителями слов, а не символами завершения командной строки; подробнее данный вопрос обсуждается в гл. 5.) Работать со знаками слабого ударения нетрудно, и поэтому, действительно, нет нужды вводить отдельный флаг команды mail
, задающий список адресатов.Несколько иной подход требуется для преобразования файла
mailinglist
из простого списка имен в программу, выдающую список имен:$ cat mailinglist
echo don whr ejs mb
Новая версия$ cx mailinglist
$ mailinglist
don whr ejs mb
$
Теперь посылка писем адресатам из списка реализуется командой:
$ mail `mailinglist`
Добавив еще одну программу, получим возможность даже изменять список пользователей в диалоге. Такая программа называется
pick
:$ pick аргументы...
и выдает свои аргументы по одному, ожидая каждый раз ответа. Результатом действия команды
pick
являются те аргументы, на которые был дан ответ y
(yes
— да); при всяком другом ответе аргумент отбрасывается. Например,$ pr `pick *.с` | lpr
Здесь вначале выдаются имена файлов, оканчивающиеся на
.с
. Выбранные имена печатаются с помощью команд pr
и lpr
. (Команда pick
не входит в состав команд седьмой версии, но она столь проста и полезна, что мы включили ее варианты в гл. 5 и 6).Допустим, вы используете второй вариант команды
mailinglist
. Тогда посылка писем адресатам don
и mb
выглядит так:$ mail `pick \`mailinglist\``
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`
3.6 Переменные языка shell
Подобно большинству языков программирования,
shell
имеет переменные, которые на программистском жаргоне называются параметрами. Такие строки, как $1
, являются позиционными параметрами-переменными, хранящими аргументы командного файла. Цифра показывает положение параметра в командной строке. Ранее мы имели дело с другими переменными языка shell
: PATH
— список каталогов, в которых происходит поиск команд, НОМЕ
— ваш начальный каталог и т.д. В отличие от переменных в обычном языке переменные, задающие позиционные параметры, не могут быть изменены; хотя PATH
представляет собой переменную со значением $PATH
, нет переменной 1 со значением $1
, т.е. $1
— это не что иное, как компактное обозначение первого аргумента.Если забыть о позиционных параметрах, переменные языка
shell
можно создавать, выбирать и изменять. Например,$ PATH=:/bin:/usr/bin
означает присваивание, изменяющее список каталогов в процессе поиска. До и после знака равенства не должно быть пробелов. Присваиваемое значение должно выражаться одним словом, и его следует взять в кавычки, если оно содержит метасимволы, которые не нужно обрабатывать. Значение переменной выбирается, если предварить имя знаком доллара:
$ PATH=$PATH:/usr/games
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin:/usr/games
$ PATH=:/usr/you/bin:/bin:/usr/bin
Восстановим значение$
He все переменные имеют специальное значение для интерпретатора. Можно создавать новые переменные, присваивая им значения. По традиции переменные, имеющие специальное значение, обозначаются прописными буквами, а обычные переменные — строчными. Типичным примером использования переменных является хранение в них длинных строк, таких, как имена файлов:
$ pwd
/usr/you/bin
$ dir=`pwd`
Запомним, где находимся$ cd /usr/mary/bin
Перейдем в другое место$ ln $dir/cx .
Используем переменную в имени файла$ ...
Поработаем некоторое время$ cd $dir
Вернемся$ pwd
/usr/you/bin