Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Руководство по Bash для начинающих
Назад Глава 3: Среда окружения Bash Вперед

Подстановки, выполняемые командной оболочкой

Общие положения

После того, как команда будет разделена на отдельные лексемы (смотрите раздел "Синтаксис командной оболочки"), над этими лексемами или словами могут быть выполнены дополнительные замены или подстановки значений. Есть восемь видов таких дополнительных действий, которые мы рассматриваем в следующих разделах в той последовательности, в какой они применяются к лексемам.

После выполнения всех этих действий, происходит удаление кавычек.

Раскрытие фигурных скобок

Раскрытие фигурных скобок - это механизм, с помощью которого можно генерировать строки произвольного вида. В шаблонах, которые при этом используются, может присутствовать необязательное НАЧАЛО, за которым между фигурными скобками идет последовательность строк, разделенных запятыми. Затем идет необязательное ЗАВЕРШЕНИЕ. Начало является префиксом всех строк, генерация которых задана внутри фигурных скобок, а завершение просто добавляется к концу каждой строки, полученной перебором слева направо строк, указанных внутри скобок.

Допускается вложенность фигурных скобок. Полученные результаты не сортируются; сохраняется порядок, определенный перебором слева направо:

franky ~> echo sp{el,il,al}l
spell spill spall

Фигурные скобки обрабатываются раньше всех других дополнительных подстановок. В полученном результате сохраняются все символы, предназначенные для следующих подстановок. Обработка строго текстовая. Bash не осуществляет интерпретацию каких-либо синтаксических конструкций, расположенных внутри фигурных скобок. Чтобы избежать конфликтов, связанных с подстановкой параметров, строка "${" при обработке фигурных скобок игнорируется.

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

Замена символа "тильда"

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

Если префиксом тильды будет "~+", то он будет заменен значением переменной PWD. Если префиксом тильды будет "~-", то он будет заменен значением переменной OLDPWD, если это значение установлено.

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

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

Для каждой операции присваивания переменной значения проверяется, присутствует ли сразу после символов ":" или "=" префикс тильды, не заключенный в кавычки. Если присутствует, то и в этом случае делается попытка замены тильды. Таким образом, при присваивании значений переменным PATH, MAILPATH и CDPATH можно использовать имена файлов с тильдой и оболочка выполнит такое присваивание с предварительной заменой тильды.

Пример:

franky ~> export PATH=$PATH:~/testdir

Строка ~/testdir будет заменена на строку $HOME/testdir, так что если $HOME равно /var/home/franky, в переменную PATH будет добавлен директорий /var/home/franky/testdir.

Подстановка значений праметров и переменных командной оболочки

Символ "$" позволяет указывать параметры, осуществлять подстановку результата работы команд или выполнять замену арифметических выражений результатом их вычисления. Имя параметра или символ, для которого будет выполняться подстановка, может быть заключен в фигурные скобки, которые не являются обязательными, но служат для того, чтобы к переменной не добавлялись символы, идущие сразу после переменной, которые могут быть проинтерпретированы как часть имени.

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

Обычным форматом для подстановки параметра является "${PARAMETER}". Вместо такой строки подставляется значение переменной "PARAMETER". Фигурные скобки необходимы, когда "PARAMETER" является позиционным параметром, в котором используется более одной цифры, либо когда за именем "PARAMETER" следует символ, который не должен интерпретироваться как часть этого имени.

Если первым символом имени "PARAMETER" является восклицательный знак, то Bash вначале производит все подстановки и замены в строке, сформированной из оставшейся части "PARAMETER", рассматриваемой как имя переменной; затем происходит подстановка значений и в дальнейшем при подстановках используется это значение, а не значение самого имени "PARAMETER". Этот механизм известен как косвенная подстановка.

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

franky ~> echo $SHELL
/bin/bash

Ниже приведен пример косвенной подстановки:

franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH

Обратите внимание, что это не то же самое, что и echo $N*.

В следующем примере создается поименованная переменная в случае, если она еще не существует:

${VAR:=value} 

Пример:

franky ~> echo $FRANKY

franky ~> echo ${FRANKY:=Franky}
Franky

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

Мы еще будем рассматривать использование фигурных скобок при работе с переменными в главе 10 "Подробнее о переменных". Более подробную информацию можно также найти в документации по Bash.

Подстановка результата работы команд

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

$(command)

или, например, внутри обратных кавычек:

`command`

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

franky ~> echo `date`
Thu Feb 6 10:06:20 CET 2003

Когда применяется старый формат записи с использованием обратных слешей, обратные слеши сохраняются за исключением случаев, когда за ними следует символ "$", "`" или "\". Первая обратная кавычка, которой не предшествует обратный слеш, закрывает процедуру подстановки результата работы команд. Если используется формат "$(COMMAND)", то все символы, находящиеся между скобками, представляют собой команду и не рассматриваются отдельно.

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

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

Арифметические выражения

Bash позволяет вычислять арифметические выражения и подставлять полученный результат. Формат записи арифметических выражений следующий:

$(( EXPRESSION ))

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

Вычисление арифметических выражений осуществляется для целых чисел фиксированной разрядности без проверки на переполнение, но деление на ноль отлавливается и распознается как ошибка. Операторы приблизительно такие же, как и в языке программирования C. Их список в порядке убывания приоритета выглядит следующим образом:

Таблица 3.4. Арифметические операторы

ОператорЧто означает

VAR++ и VAR--

Пост-инкремент и пост-декремент переменной

++VAR и --VAR

Пред-инкремент и пред-декремент переменной

- и +

Унарные минус и плюс

! и ~

Логическое и побитовое отрицание

**

Возведение в степень

*, / и %

Умножение, деление, остаток от деления

+ и -

Сложение, вычитание

<< и >>

Левый и правый побитовый сдвиг

<=, >=, < и >

Операторы сравнения

== и !=

Равенство и неравенство

&

Побитовое И

^

Побитовое исключающее ИЛИ

|

Побитовое ИЛИ

&&

Логическое И

||

Логическое ИЛИ

expr ? expr : expr

Условный оператор

=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^= и |=

Операции присваивания

,

Разделитель между выражениями

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

Константы с лидирующим 0 (нулем) интерпретируются как восьмеричные числа. Лидирующие "0x" или "0X" обозначают шестнадцатеричные числа. В остальных случаях числа указываются в формате "[BASE '#'] N", где "BASE" является десятичным числом между 2 и 64, которое представляет собой основание числа, а N является собственно числом по этому основанию. Если основание "BASE '#'" не указано, то используется основание 10. Для представления цифр, больших 9, используются строчные буквы, заглавные буквы, "@" и "_", в указанном порядке. Если основание "BASE" меньше или равно 36, то строчные и заглавные буквы могут быть использованы для представления чисел от 10 до 35 как взаимозаменяемые.

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

Везде, где это возможно, пользователи Bash должны стараться пользоваться квадратными скобками:

$[ EXPRESSION ] 

Но, в этом случае будет только вычисляться результат EXPRESSION, и проверка делаться не будет:

franky ~> echo $[365*24]
8760

Примеры практического использования в скриптах смотрите в разделе "Сравнение чисел".

Подстановка процессов

Подстановка процессов поддерживается в системах, в которых есть именованные конвейеры (FIFO) или метод /dev/fd, предназначенный для именования открытых файлов. Используется следующий формат:

<(LIST) 

или

>(LIST) 

Выполняется процесс LIST, причем его входной и выходной потоки подключены к конвейеру FIFO или к некоторому файлу в /dev/fd. Имя этого файла передается в качестве аргумента в текущую команду как результат подстановки. Если используется формат ">(LIST)", будет записан файл, который будет входом для LIST. Если используется формат "<(LIST)", файл передается в качестве аргумента, который должен быть прочитан с тем, чтобы получить выход LIST. Обратите внимание, что между символами < или > и левой скобкой пробелов быть не должно, иначе эта конструкция будет интерпретирована как операция перенаправления.

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

Более подробную информацию смотрите в разделе "Перенаправление и дескрипторы файлов".

Разбиение на слова

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

Оболочка рассматривает каждый символ, входящий в переменную $IFS, как разделитель и по этим символам разбивает результат других подстановок на слова. Если значение IFS не установлено, или его значение равно точно значению "'<пробел><tab><новая строка>'", что задано по умолчанию, то разделителем слов будет служить любая последовательность символов, указанных в IFS. Если в IFS задано значение, отличающее от значения, задаваемого по умолчанию, то в начале и конце слов последовательности пробельных символов "пробел" и "Tab" игнорируются только в тех случаях, когда они присутствуют в значении IFS (т. е. являются пробельными символами IFS). Любой символ из IFS, не являющийся пробельным символом IFS, вместе с любыми соседними пробельными символами IFS, будут рассматриваться как разделители полей. Последовательности пробельных символов IFS также рассматриваются как разделители. Если значение IFS не определено, то разбиение на слова не происходит.

Явные пустые аргументы ("""" или "''") сохраняются. Неявные пустые аргументы, которые указаны без кавычек и были получены при подстановке параметров, не имеющих значение, удаляются. Если параметр, не имеющий значение, заменяется двойными кавычками, то результирующему аргументу будет присвоено значение null и он будет сохранен.

Подстановки и разбиение на слова

Если никаких замен и подстановок не производилось, то и разбиение на слова также не выполняется.

Подстановки имен файлов

После того, как будет выполнено разбиение на слова, и если не установлен параметр -f (смотрите раздел "Отладка скрипта по частям"), Bash проверит каждое слово на наличие символов "*", "?", и "[". Если встретится какой-либо из этих символов, то слово рассматривается как ШАБЛОН и заменяется отсортированным по алфавиту списком имен файлов, соответствующих шаблону. Если соответствующие имена файлов найдены не будут и отключен параеметр nullglob, то слово изменено не будет. Если параметр nullglob включен и соответствий не найдено, то слово удаляется. Если включен параметр nocaseglob командной оболочки, то сравнение производится без учета регистра символов алфавита.

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

Для ограничения множества имен файлов, соответствующих шаблону, может использоваться переменная GLOBIGNORE. Если переменная GLOBIGNORE установлена, то из списка соответствий удаляются все имена файлов, которые также соответствуют одному из шаблонов, указанных в переменной GLOBIGNORE. Однако настройка переменной GLOBIGNORE влияет на результаты сравнений, полученных при включенном параметре dotglob. Результатом будет то, что все другие имена файлов, начинающиеся с ".", будут считаться совпадающими. Чтобы добиться результата, когда имена файлов, начинающиеся с ".", будут игнорироваться, добавьте в переменную GLOBIGNORE шаблон ".*". Если значение переменной GLOBIGNORE не задано, параметр dotglob отключается.


Предыдущий раздел: Оглавление Следующий раздел:
Символы кавычек   Алиасы