$ who
you tty2 Sep 28 07:51 rhh tty4 Sep 28 10:02
moh tty5 Sep 28 09:38 ava tty6 Sep 28 10:17
$ cat nu who | wc -l
$ sh < nu
4
$
Результат получился таким же, каким бы он был при задании команды
who | wc -l
с терминала. Опять-таки, как и большинство программ, интерпретатор берет входной поток из файла, если он указан в качестве аргумента; вы с тем же успехом могли задать:
$ sh nu
Однако досадно вводить "
sh
" каждый раз; во всяком случае эта запись длиннее и создает различия между программами, написанными, например, на Си, и программами, написанными с помощью
shell
.
[9] Поэтому если файл предназначен для выполнения и если он содержит текст, то интерпретатор считает, что он состоит из команд. Такие файлы называются командными. Все, что вам нужно сделать, это объявить файл
nu
выполняемым, задав
$ chmod + x nu
а затем вы можете вызывать его посредством
$ nu
С этого момента те, кто используют файл nu, не смогут определить способ его создания.
Способ, с помощью которого интерпретатор на самом деле выполняет
nu
, сводится к созданию нового процесса интерпретатора, как если бы вы задали
$ sh nu
Этот процесс-потомок называется порожденным интерпретатором, т.е. процессом интерпретатора, возбужденным вашим текущим интерпретатором. Но команда
sh nu
— это не то же самое, что
sh < nu
, поскольку в первом случае стандартный входной поток все еще связан с терминалом. Пока команда
nu
выполняется только в том случае, если она находится в вашем текущем каталоге (при условии, конечно, что текущий каталог включен в
PATH
, а именно это мы и предполагаем с настоящего момента). Чтобы сделать команду nu частью вашего репертуара независимо от того каталога, с которым вы работаете, занесите ее в свой собственный каталог
bin
и добавьте
/usr/you/bin
к списку каталогов поиска:
$ pwd /usr/you
$ mkdir bin
Создать bin, если его еще не было
$ echo $PATH
Проверить Path, чтобы убедиться
:/usr/you/bin:/bin:/usr/bin
Должно быть нечто похожее
$ mv nu bin
Установить команду nu в bin
$ ls nu
nu not found
Она действительно исчезла
из текущего каталога
$ nu
4
Но интерпретатор ее находит
$
Конечно, ваша переменная
PATH
должна быть правильно определена в файле
.profile
, чтобы вам не приходилось переопределять ее при каждом входе в систему.
Существуют и другие простые команды, которые вы можете адаптировать к среде по своему вкусу и создавать таким же способом. Нам показалось удобным иметь следующие команды:
•
cs
для посылки подходящей последовательности специфических символов с целью очистки экрана вашего терминала (24 символа перевода строки — практически универсальное решение);
•
what
для запуска
who
и
ps -а
, чтобы сообщить, кто работает в системе и что он делает;
•
where
для вывода идентифицированного названия используемой системы UNIX. Это удобно, если вы постоянно работаете с несколькими версиями. (Установка
PS1
служит для подобной цели.)
Упражнение 3.9
Просмотрите каталоги
/bin
и
/usr/bin
, чтобы выяснить, как много команд являются в действительности командными файлами. Можно ли это сделать с помощью одной команды? Подсказка: посмотрите
file(1)
. Насколько точно предположение, основанное на длине файла?
3.4 Аргументы и параметры команд
Хотя команда
nu
, как она задумывалась, удовлетворяет своему назначению, многие программы на языке
shell
могут обрабатывать аргументы, так что при их запуске можно задавать имена файлов и флаги.
Допустим, вы хотите создать программу с именем
cx
для установки права доступа к файлу на выполнение, так что
$ cx nu
есть сокращенная запись для
$ chmod +x nu
Вы уже знаете почти все, чтобы это сделать. Вам нужен файл
cx
, содержимое которого суть
chmod +x filename
Единственное, что требуется выяснить — как сообщить команде
cx
имя файла, так как при каждом запуске
cx
оно будет иным.
Если интерпретатор выполняет командный файл, то каждое вхождение
$1
заменяется первым аргументом, каждое вхождение
$2
— вторым и т.д. до
$9
. Поэтому если файл
cx
содержит строку
chmod +x $1
то при выполнении команды
$ cx nu
порожденный интерпретатор заменит "
$1
" на первый аргумент "
nu
". Рассмотрим всю последовательность операций:
$ echo 'chmod +x $1' >cx
Вначале создадим cx
$ sh cx сх
Сделать сам файл cx выполняемым
$ echo echo Hi, there! >hello
Приготовим тест
$ hello
Попробуем
hello: cannot execute
$ cx hello
Сделаем файл выполняемым
$ hello
Попробуем снова
Hi, there!
Работает
$ mv cx /usr/you/bin
Установим команду cx
$ rm hello
Уберем ненужное