Главная » Программирование для UNIX » Аргументы и параметры команд UNIX

0

Большинство программ оболочки интерпретируют аргументы, поэтому когда команда запускается, можно указать, например, имена фай лов и параметры (хотя некоторые команды, например nu, успешно работают  и без аргументов).

Предположим, что требуется создать программу cx, которая изменяла бы код прав  доступа к файлу на исполняемый, таким образом,

$ cx  nu

представляет собой краткую запись

$ chmod  +x nu

Вам уже  известно почти  все, что для этого необходимо. Нужен файл с именем cx, который содержал бы

chmod  +x имя5файла

Единственное, о чем еще не говорилось, так  это о том,  каким образом сообщить команде cx имя файла, если при каждом запуске cx оно будет разным.

Когда  оболочка выполняет командный файл, каждое вхождение $1 заменяется на первый аргумент, каждое вхождение $2 – на второй аргумент, и так до $9. Поэтому, если файл cx содержит

chmod  +x $1

то когда запускается команда

$ cx  nu

подоболочка заменяет $1 на первый аргумент – nu.

Давайте посмотрим на всю последовательность операций:

$ echo ‘chmod +x $1′  >cx                  Сначала создать  cx

$ sh  cx  cx                                             Сделать файл cx  исполняемым

$ echo echo Hi,  there!  >hello         Создать тестовую программу

$ hello                                               Опробовать ее

hello: cannot  execute

$ cx  hello                                         Сделать ее исполняемой

$ hello                                              Попробовать еще раз

Hi,  there!                                       Работает

$ mv  cx  /usr/you/bin                       Установить cx

$ rm hello                                      Очистить

$

Обратите внимание, что было введено

$ sh  cx  cx

В точности то же  самое  автоматически бы сделала оболочка, если  бы команда cx уже была исполняемой и было бы введено

$ cx  cx

Что  делать, если  необходимо наличие нескольких аргументов, например, чтобы  программа типа  cx могла обрабатывать сразу  несколько файлов? Первый, «топорный» способ, состоит в том,  чтобы  задать для  программы оболочки девять аргументов:

chmod  +x $1 $2 $3 $4 $5 $6 $7 $8 $9

(Работает только для 9 аргументов, потому что строка $10 воспринимается как «первый аргумент, $1, за которым следует 0»!). Если пользователь  такого командного файла задает меньше, чем девять аргументов, место  отсутствующих занимают пустые строки; в  результате подоболочка передает chmod только те аргументы, которые действительно были определены. То есть этот способ работает, но имеет  явные недостатки, к тому же он не подходит, если задано более девяти аргументов.

Предвосхищая возможный поворот событий, оболочка предоставляет шаблон $*, который означает «все аргументы». Тогда правильный способ определения cx выглядит так:

chmod  +x $*

Сколько бы аргументов ни было задано, все работает.

Имея в  своем  репертуаре $*,  можно создать  несколько удобных командных файлов, например lc или m:

$ cd /usr/you/bin

$ cat  lc

# lc: сосчитать  количество строк  в файлах  wc –l  $*

$ cat  m

# m:  краткое  обозначение  для mail mail  $*

$

Обе программы осмысленно работают и без аргументов. Если  аргументы не заданы, то $* будет пустым, и вообще  никакие аргументы не будут переданы wc и mail. Но и без аргументов, и с ними команда вызывается правильно:

$ lc /usr/you/bin/*

1  /usr/you/bin/cx 2  /usr/you/bin/lc 2  /usr/you/bin/m

1              /usr/you/bin/nu

2              /usr/you/bin/what

1  /usr/you/bin/where 9  total

$ ls /usr/you/bin | lc

6

$

Эти команды и команды из других примеров данной главы относятся к разряду личных программ. Личными называются программы, кото рые пишутся пользователем для  себя и помещаются в личный каталог

/bin. К ним  не предоставляется общий доступ, потому  что они  слишком  сильно зависят от вкуса конкретного пользователя. В главе 5 будут  представлены  основы   написания  программ  оболочки,  которые подходят для общего использования.

Аргументами командного файла не обязательно должны быть  имена файлов. Разберем пример просмотра персонального личного телефонного каталога. Если  существует файл /usr/you/lib/phone–book, который содержит что-то вроде:

dial–a–joke    212–976–3838 dial–a–prayer    212–246–4200 dial  santa    212–976–3636

dow  jones  report   212–976–4141

то просмотреть его можно командой grep. (Неплохим местом для  хра нения персональных  баз  данных является каталог  /lib.) Формат информации не имеет  значения для  grep, поэтому можно искать имена,

адреса, почтовые индексы, то есть  все, что угодно. Давайте создадим программу «справочная линия» и назовем ее 411  в честь номера телефонной справочной линии нашего района:

$ echo ‘grep  $* /usr/you/lib/phone-book’  >411

$ cx  411

$ 411 joke

dial–a–joke   212–976–3838

$ 411 dial

dial–a–joke    212–976–3838 dial–a–prayer    212–246–4200 dial  santa    212–976–3636

$ 411 ‘dow jones’

grep:  can’t open jones                     Что5то не так

$

Последний пример приведен для  того, чтобы  показать  возможные трудности: несмотря на то, что dow  jones  передан 411 как единый аргу мент, он содержит пробел  и уже  не заключен в кавычки, поэтому подоболочка, которая интерпретирует команду 411, преобразует его в два аргумента для grep: получается, как будто было введено

$ grep  dow jones  /usr/you/lib/phone-book

а это, естественно, неправильно.

Есть средство, способное помочь в такой ситуации, оно использует особенность обработки оболочкой двойных кавычек. Все, что заключено в ‘…’, остается нетронутым, а вот внутрь "…" оболочка заглядывает в поиске $, \ и `…`. Поэтому если изменить 411 таким образом:

grep  "$*"  /usr/you/lib/phone–book

то строка $* будет заменена аргументами, но команде grep будет передаваться как один аргумент, даже если в ней будут содержаться пробелы.

$ 411 dow jones

dow  jones  report   212–976–4141

$

Кстати, заодно  можно сделать grep (а значит, и 411) не зависящей от регистра, для этого укажем параметр –y:

$ grep  -y  шаблон …

Если  указан параметр -y, то строчные буквы из шаблона будут  сопоставляться с прописными буквами из входного потока. (Этот параметр включен в grep из седьмой версии , но отсутствует в некоторых других системах.)

В обсуждении аргументов команд есть  пять  пунктов, которые будут отложены до главы 5, но все же один из них  заслуживает упоминания

прямо сейчас. Аргумент $0 является именем исполняемой программы: в cx $0 – это cx. Нестандартное использование $0 можно встретить в реализации программ 2,  3,  4,  …,  которые печатают свой  вывод  в несколько колонок:

$ who  | 2

drh

tty0

Sep 28 21:23

cvw

tty5

Sep 28 21:09

dmr

tty6

Sep 28 22:10

scj

tty7

Sep 28 22:11

you

tty9

Sep 28 23:00

jlb

ttyb

Sep 28 19:58

$

Реализации 2,  3,  … идентичны, на самом  деле все они представляют собой ссылки на один и тот же файл:

$ ln  2  3;  ln  2  4;  ln  2  5;  ln  2  6

$ ls -li  [1-9]

16722 –rwxrwxrwx  5 you               51 Sep 28 23:21  2 16722 –rwxrwxrwx  5  you              51 Sep 28  23:21  3 16722  –rwxrwxrwx  5 you               51  Sep 28 23:21  4 16722  –rwxrwxrwx  5 you               51 Sep 28 23:21  5 16722 –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  –l1  $*

$

Параметр –t подавляет вывод заголовка наверху страницы, а параметр

–ln  устанавливает длину страницы равной n строкам. Имя программы становится аргументом, задающим количество колонок для pr, так что вывод печатается построчно в количество колонок, определенное аргу ментом $0.

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии