Переменные и аргументы shell-процедур
Переменные обозначаются именами. Значения могут присваиваться им привычным способом, то есть посредством команд вида:
имя=значение [имя=значение] ...
Все значения в языке shell трактуются как текстовые. Подчеркнем, что, в соответствии с этими требованиями, конструкция
имя=значение
должна представлять собой одно слово - в ней не может быть пробелов.
Обычно в языках программирования ясно из контекста, где подразумевается имя переменной, а где значение. Так, в левой части оператора присваивания обычно используется имя, в правой - значение. В shell все не так. Переход от имени переменной к значению помечается посредством явной операции $. Если в команде встречается конструкция
$имя
то вместо нее интерпретатор shell подставляет значение переменной с указанным именем. Допускается и запись
${имя}
с тем же смыслом, если нужно отделить имя от последующего текста.
Рассмотрим пример. После выполнения команд (см. листинг 2.6) - утилита echo (эхо) выдает на стандартный вывод свои аргументы - на экране появится результат вывода значений переменных (см. листинг 2.7).
a=value_of_variable b=1+2 echo a = $a echo b = $b
Листинг 2.6. Присваивание и извлечение значение переменных. (html, txt)
a = value_of_variable b = 1+2
Листинг 2.7. Результат вывода значений переменных. (html, txt)
Значения формальных аргументов shell-процедур обозначаются как
$цифра
$0 - это имя интерпретируемой shell-процедуры. Если заданных при вызове команды фактических аргументов меньше, чем 9, "лишние" формальные аргументы получают пустые значения. О том, как добраться до фактических аргументов с номерами большими, чем 9, будет сказано ниже (см. управляющую конструкцию for и команду shift).
В качестве примера рассмотрим shell-процедуру, которая выдает на стандартный вывод свое имя и значения трех первых аргументов (см. листинг 2.8).
echo Имя команды: $0 echo Значение первого аргумента: $1 echo Значение второго аргумента: $2 echo Значение третьего аргумента: $3
Листинг 2.8.
Пример shell-процедуры. (html, txt)
Пусть приведенный текст помещен в файл с именем three_args. Тогда после выполнения команды (см. листинг 2.9) на экране появится ее результат (см. листинг 2.10).
three_args arg1 . - arg4
Листинг 2.9. Пример вызова shell-процедуры с аргументами. (html, txt)
Имя команды: three_args Значение первого аргумента: arg1 Значение второго аргумента: . Значение третьего аргумента: -
Листинг 2.10. Результат выполнения shell-процедуры. (html, txt)
Поскольку в тексте shell-процедуры упомянуты только первые 3 аргумента, значения аргументов с большими номерами (даже если они заданы, как в приведенном примере) не влияют на ее работу.
Команда
three_args arg1 --
выдаст другой результат (см. листинг 2.11):
Имя команды: three_args Значение первого аргумента: arg1 Значение второго аргумента: -- Значение третьего аргумента:
Листинг 2.11. Еще один результат выполнения shell-процедуры. (html, txt)
Значение третьего формального аргумента пусто.
Прежде чем начнется выполнение командной строки, т. е. будет вызвана заданная в ней команда, строку обрабатывает 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. Пример сопоставления с образцом. (html, txt)
Выдать первый элемент маршрутного имени файла (см. далее) можно с помощью команд, показанных в листинге 2.13:
f=маршрутное_имя echo ${f%%/*}
Листинг 2.13. Второй пример сопоставления с образцом. (html, txt)
Последний элемент выдается командой, приведенной в листинге 2.14:
echo ${f##*/}
Листинг 2.14. Третий пример сопоставления с образцом. (html, txt)