Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2290 / 579 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 2:

Язык shell

Переменные и аргументы shell-процедур

Переменные обозначаются именами. Значения могут присваиваться им привычным способом, то есть посредством команд вида:

имя=значение [имя=значение] ...

Все значения в языке shell трактуются как текстовые. Подчеркнем, что, в соответствии с этими требованиями, конструкция

имя=значение

должна представлять собой одно слово - в ней не может быть пробелов.

Обычно в языках программирования ясно из контекста, где подразумевается имя переменной, а где значение. Так, в левой части оператора присваивания обычно используется имя, в правой - значение. В shell все не так. Переход от имени переменной к значению помечается посредством явной операции $. Если в команде встречается конструкция

$имя

то вместо нее интерпретатор shell подставляет значение переменной с указанным именем. Допускается и запись

${имя}

с тем же смыслом, если нужно отделить имя от последующего текста.

Рассмотрим пример. После выполнения команд (см. листинг 2.6) - утилита echo (эхо) выдает на стандартный вывод свои аргументы - на экране появится результат вывода значений переменных (см. листинг 2.7).

a=value_of_variable
b=1+2
echo a = $a
echo b = $b
Листинг 2.6. Присваивание и извлечение значение переменных.
a = value_of_variable
b = 1+2
Листинг 2.7. Результат вывода значений переменных.

Значения формальных аргументов shell-процедур обозначаются как

$цифра

$0 - это имя интерпретируемой shell-процедуры. Если заданных при вызове команды фактических аргументов меньше, чем 9, "лишние" формальные аргументы получают пустые значения. О том, как добраться до фактических аргументов с номерами большими, чем 9, будет сказано ниже (см. управляющую конструкцию for и команду shift ).

В качестве примера рассмотрим shell-процедуру, которая выдает на стандартный вывод свое имя и значения трех первых аргументов (см. листинг 2.8).

echo Имя команды: $0
echo Значение первого аргумента: $1
echo Значение второго аргумента: $2
echo Значение третьего аргумента: $3
Листинг 2.8. Пример shell-процедуры.

Пусть приведенный текст помещен в файл с именем three_args. Тогда после выполнения команды (см. листинг 2.9) на экране появится ее результат (см. листинг 2.10).

three_args arg1 . - arg4
Листинг 2.9. Пример вызова shell-процедуры с аргументами.
Имя команды: three_args
Значение первого аргумента: arg1
Значение второго аргумента: .
Значение третьего аргумента: -
Листинг 2.10. Результат выполнения shell-процедуры.

Поскольку в тексте shell-процедуры упомянуты только первые 3 аргумента, значения аргументов с большими номерами (даже если они заданы, как в приведенном примере) не влияют на ее работу.

Команда

three_args arg1 --

выдаст другой результат (см. листинг 2.11):

Имя команды: three_args
Значение первого аргумента: arg1
Значение второго аргумента: --
Значение третьего аргумента:
Листинг 2.11. Еще один результат выполнения shell-процедуры.

Значение третьего формального аргумента пусто.

Прежде чем начнется выполнение командной строки, т. е. будет вызвана заданная в ней команда, строку обрабатывает shell, выполняющий в ней некоторые подстановки. С одной из них - значения переменной вместо конструкции $имя - мы уже познакомились. Язык shell содержит ряд аналогичных конструкций. Рассмотрим их.

Там, где в командной строке встречается запись вида

${имя:-слово}

вместо нее подставляется значение переменной с указанным именем, если это значение непусто, в противном случае подставляется слово. Например, при наличии в shell-процедуре присваивания

initdir=${1:-/}

переменная initdir получит значение первого аргумента, если оно непусто. Если же процедуру вызвали без аргументов, значением initdir станет символ /. Подобные конструкции - удобный способ использования подразумеваемых значений.

Запись вида

${имя:=слово}

влечет присваивание нового значения (слово) переменной с заданным именем, только если ее старое значение не установлено или пусто (удобный способ присваивания переменным подразумеваемых значений). Вместо всей конструкции в командную строку подставляется итоговое (непустое старое или присвоенное новое) значение переменной.

Конструкция

${имя:?слово}

предназначена для выдачи в стандартный протокол сообщения об ошибке, если значение переменной с заданным именем не установлено или пусто, после чего неинтерактивный shell завершает работу с ненулевым кодом возврата. Непустое значение подставляется в командную строку, и интерпретация командного файла продолжается обычным образом.

Вместо конструкции

${имя:+слово}

подставляется слово, если значение переменной с заданным именем непусто; в противном случае не подставляется ничего. Такой способ удобен для использования альтернативных значений.

Если в приведенных выше конструкциях опустить двоеточие, будет отменена проверка непустоты значения (останется лишь проверка того, установлено ли значение переменной с заданным именем. В остальном смысл конструкций остается прежним.

Shell содержит базовые средства для обработки цепочек символов. Так, вместо конструкции

${#имя}

подставляется число символов в значении переменной с заданным именем.

Предоставляется четыре конструкции для сопоставления с образцом:

${имя%слово}
${имя%%слово}
${имя#слово}
${имя##слово}

Во всех случаях слово рассматривается как образец ( шаблон, см. далее); после сопоставления с ним подставляется значение переменной с заданным именем, из которого удален минимальный (максимальный) сопоставленный суффикс ( префикс ).

Приведем несколько примеров. Для их понимания достаточно знать, что шаблон * сопоставляется с произвольной цепочкой символов, в том числе с пустой.

После присваивания переменной

HOME=/home/galat

команда

echo ${#HOME}

выдаст 11.

Заменить в имени файла суффикс .f на .for можно с помощью команд, показанных в листинге 2.12:

f=file.f
mv $f ${f%.f}.for
Листинг 2.12. Пример сопоставления с образцом.

Выдать первый элемент маршрутного имени файла (см. далее) можно с помощью команд, показанных в листинге 2.13:

f=маршрутное_имя
echo ${f%%/*}
Листинг 2.13. Второй пример сопоставления с образцом.

Последний элемент выдается командой, приведенной в листинге 2.14:

echo ${f##*/}
Листинг 2.14. Третий пример сопоставления с образцом.
Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?

Павел Храмцов
Павел Храмцов
Россия
Денис Комаров
Денис Комаров
Россия, Москва