Добавив еще одну программу, получим возможность даже изменять список пользователей в диалоге. Такая программа называется
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`
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
$
Встроенная в интерпретатор команда
set
показывает значения всех определенных вами переменных. Для просмотра одной или двух переменных более подходит команда
echo
:
$ set
HOME=/usr/you
IFS=
PATH=:/usr/you/bin:/bin/:/usr/bin
PS1=$
PS2=>
dir=/usr/you/bin
$ echo $dir
/usr/you/bin
$
Значение переменной связано с той копией интерпретатора, который создал ее, и автоматически не передается процессам — потомкам интерпретатора.
$ x=Hello
Создание x
$ sh
Новый shell
$ echo $x
Происходит только перевод строки,
x не определено в порожденном интерпретаторе
$ ctl-d
Возврат в исходный интерпретатор
$ echo $x
Hello
x по-прежнему определено
$
Это означает, что в командном файле нельзя изменить значение переменной, поскольку выполнением командного файла управляет порожденный интерпретатор:
$ echo 'x="Good bye"
Создание shell-файла из двух строк…
> echo $x' >setx
…для определения и печати x
$ cat setx
x="Good Bye"
echo $x
$ echo $x
Hello
x есть Hello в исходном интерпретаторе
$ sh setx
Good Bye
x есть Good Bye в порожденном интерпретаторе…
$ echo $x
Hello
…но по-прежнему есть Hello в текущем интерпретаторе
$
Однако бывают ситуации, когда было бы полезно изменять переменные интерпретатора в командном файле. Очевидным примером является файл, добавляющий новый каталог к вашей переменной
PATH
. Поэтому интерпретатор предоставляет команду
'.'
(точка), которая выполняет команды из файла в текущем, а не порожденном интерпретаторе. Первоначально это было задумано для удобства пользователей, чтобы они могли повторно выполнять свой файл
.profile
, не входя заново в систему, но в принципе это открывает и другие возможности: