Перенаправление в bash

Перенаправление в bash

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

Каждое перенаправление, которому предшествует число дескриптора файла, вместо него может стоять слово вида {ИмяПеременной}. В этом случае для каждого оператора перенаправления кроме «>&-» и «<&-», оболочка будет выделять дескриптор файла более 10 и присвоит его ИмяПеременной. Если «>&» или «<&» предшествуют {ИмяПеременной}, значение переменной определяет дескриптор файла для закрытия.

В следующем описании если число дескриптора файла не указано, и первый символ является оператором перенаправления «<», выполняется перенаправление стандартного ввода (дескриптор файла 0). Если первый символ является оператором перенаправления «>», выполняется перенаправление стандартного вывода (дескриптор файла 1).

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

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

ls > dirlist 2>&1

направляет стандартный вывод и стандартные ошибки в файл dirlist, в то время как команда.

ls 2>&1 > dirlist

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

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

/dev/fd/fd

Если fd является целым числом, дескриптор файла, fd дублируется.

/dev/stdin

Дескриптор файла 0 дублируется.

/dev/stdout

Дескриптор файла 1 дублируется.

/dev/stderr

Дескриптор файла 2 дублируется.

/dev/tcp/host/port

Если host является правильным именем хоста или интернет адреса и port является целым числом порта или именем службы, bash пытается открыть соединение TCP к соответствующему разъёму.

/dev/udp/host/port

Если host является правильным именем хоста или интернет адреса и port является целым числом порта или именем службы, bash пытается открыть соединение UDP к соответствующему разъёму.

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

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

Стоит отметить что встроенная команда exec может сделать перенаправление в текущей оболочке.

Перенаправление ввода

 

Перенаправление ввода вызывает файл, имя которого получается в результате подстановки слова, открыть для чтения файловый дескриптор «n» или стандартного ввода(дескриптор файла 0), если n не указано.

 

Общий формат для перенаправления ввода:

 

[n]<слово

 

Перенаправление вывода

 

Перенаправление вывода вызывает файл, имя которого получается в результате подстановки слова, открыть для записи на файловый дескриптор «n» или стандартный вывод (дескриптор файла 1) если «n» не указан. Если файл не существует то он создается, если же он существует то он усекается до нулевого размера.

 

Основной формат перенаправления вывода:

 

[n]>слово

 

Если оператор перенаправления «>» и опция встроенной команды set, noclobber была включена, то переадресация будет ошибочной, если файл, имя которого получается в результате подстановки слов существует и является обычным файлом. Если это оператор перенаправления «>|» или оператор перенаправления «>» но опция noclobber встроенной команды set не включена, перенаправление выполняется даже если файл с именем слова существует.

 

Добавление перенаправления выхода

 

Перенаправление вывода таким образом вызывает файл, имя которого получается в результате подстановки слов, файл будет открыт для добавления на файловый дескриптор «n» или стандартный вывод(дескриптор файла 1) если «n» не указана. В том случае если файл не существует он будет создан.

 

Обычный формат для добавления выхода:

 

[n]>>слово

 

Перенаправление стандартного вывода и стандартной ошибки

 

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

 

Есть два формат для перенаправления стандартного вывода и вывода об ошибке:

 

&>слово

 

и

 

>&слово

 

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

 

>слово 2>&1

 

Добавление стандартного вывода и стандартной ошибки

 

Эта конструкция позволяет оба стандартных вывода, стандартный вывод (дескриптор файла 1) и стандартный вывод ошибок (дескриптор файла 2), добавить в файл, именем которого является слово расширения.
Формат для добавления стандартного вывода и стандартной ошибки:

 

&>>слово

 

Это семантически эквивалентно

 

>>слово 2>&1

 

Here-document

 

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

 

Формат документации здесь выгдядит:

 

<<[-]слово

here-document

delimiter

 

Нет параметров расширения, подстановки команд, арифметических расширений или расширения имен файлов, пока выполняется слово. Если какой-либо символ в слове является кавычкой, разделителем является результат удаления кавычек в слове, и линии в here-document не расширяются. Если слово без кавычек, все линии here-document подвергаются параметрам расширения, подстановке команд, и арифметических расширений. В ином же случае, последовательность символов «\» игнорируется и «\» должен использовать кавычки символы «\», «$» и «».

 

Если оператором перенаправления является «<<-», то все ведущие символы табуляции удаляются из входящих линий и строки содержащий контайнеры.Это позволяет here-documents в shell скриптах с отступом естественным образом.

 

Here Strings

 

Переменная here-document формата:

 

<<<слово

 

Слово раскрывается и передается этой команде на стандартный ввод.

 

Дублирование дескрипторов файлов

 

Оператор перенаправления:

 

[n]<&слово

 

используется для дублирования дескрипторов входных файлов. Если слово расширяется до одной или нескольких цифр, дескриптор файла обозначается « делает копию этого дескриптора файла. Если цифры в слове не указывают дескриптор файла открыт для входа, возникает ошибка перенаправления. Если слово имеет значение «», файловый дескриптор «n» закрыт. Если «n» не указано, стандартный ввод (дескриптор файла 0) используется.

 

Оператор

 

[n]>&слово

 

используется аналогично дублирования дескрипторов выходного файла. Если «n» не указано, стандартный вывод (дескриптор файла 1) используется. Если цифры с слове не указывают дескриптор файла открываемого для вывода, возникает ошибка перенаправления. Как частный случай, если «n» не указана и слово не расширяется к одной или более цифрам, стандартный вывод и стандартная ошибка перенаправляются как было описано ранее.

 

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

 

Оператор перенаправления

 

[n]<&digit-

 

перемещает digit файлового дескриптора в файловый дескриптор «n» или стандартный ввод(дескриптор файла 0) если «n» не указан. digit закрывается после того как «n» дублируется.

 

Кроме того, оператор перенаправления

 

[n]>&digit-

 

перемещает файловый дескриптор digit в файловый дескриптор «n» или стандартный вывод(дескриптор файла 1) если «n» не указан.

 

Открытие дескрипторов файлов для чтения и записи

 

Оператор перенаправления

 

[n]<>слово

 

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

Разбиение на слова, Подстановка имен файлов, Соответствия шаблонов и Удаление кавычек в bash

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

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

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

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

Стоит отметить, что если расширение не происходит, разбиение не выполняется.

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

После разбиения на слова, если опция -f не установлена, bash считывает каждое слово символов «*», «?», и «[». Если появляется один из этих символов, то слово рассматривается как шаблон и заменяется в алфавитном порядке списком имен файлов, соответствующих шаблону. Если совпадений имен файлов не найдено, и в shell не включена опция nullglob, то слово остаётся неизменным. Если опция nullglob установлена, и совпадений не найдено, слово удаляется. Если установлена опция failglob, и никаких совпадений не найдено, выводится сообщение об ошибке, и команда не выполняется. Если включена опция nocaseglob, совпадение проводится без учета регистра алфавитных символов. Следует отметить что здесь используется диапазон [a-z], любые же иные буквы могут быть включены в зависимости от настройки LC_COLLATE. Когда используется шаблон для расширения имен файлов, символ «.» в начале имени или сразу после косой черты, должны полностью совпадать, если опция shell не установлена. При сопоставлении путей имен файлов, косая черта всегда должна сопоставляться явно. В иных случаях символ «.» специально не рассматривается. Описание команд nocaseglob, nullglob, failglob и dotglob для shell я буду писать в будущем.

Переменная shell GLOBIGNORE может быть использована для ограничения множества имен файлов соответствующих шаблону. Если GLOBIGNORE установлена, каждое совпадение имени файла, которое совпадает с одним из шаблонов в GLOBIGNORE, удаляется из списка совпадений. Имена файлов «.» и «..» всегда игнорируется когда GLOBIGNORE установлена и не пуста. Однако настройка GLOBIGNORE в непустое значение имеет эффект при включении shell опции dotglob, так что все иные имена файлов которые начинаются с «.» будут совпадать. Чтобы вернуть старое поведение вне зависимости от имен файлов, начинающиеся с «.» сделайте «.*» один из шаблонов в GLOBIGNORE. Опция dotglob недоступна в том случае если GLOBIGNORE не установлен.

Соответствия шаблонов

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

Специальные символы шаблона имеют следующие значения:

* Соответствует любой строке, включая пустую строку. Когда shell опция globstar включена и «*» используется в контексте расширения имен файлов, два соседних «*s», используется как единый шаблон который будет соответствовать всем файлам и нулю или большинству каталогов и подкаталогов. Если после «/» два соседних «*s» соответствуют только каталогам и подкаталогам.

? Соответствует любому одному символу.

[…] Соответствует любому из символов в скобках. Пара символов разделенные дефисом, обозначает выражение диапазона, который находится между этими двумя символами, включительно, использующие текущую локализацию и кодировку. Если первый символ следующий за «[» является «!» или «^» то любые символы не согласовываются. Порядок сортировки символов в диапазоне выражений определяется с учетом текущей локализации и значения shell переменной LC_COLLATE если установлено. «» можно согласовать включая из в качестве первого или последнего установленного символа. «]» могут быть согласованны путем включения его в качестве первого установленного символа.

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

alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit

Символы класса соответствуют любому символу, принадлежащему к этому классу. Символ класса word соответствует буквам, цифрам и символу «_».

В пределах [и] эквивалент класса может быть задан с помощью конструкции [=c=], которая соответствует всем символам в соответствии с текущей локалью как символ «c».

В пределах [и] синтаксис [.symbol.] соответствует упорядоченному symbol symbol.

Если shell опция extglob включается в помощью встроенной shopt, несколько расширенных шаблоном оператором признаются. В следующем описании, шаблон это список из одного или нескольких шаблонов разделенных «|». Композитные шаблоны могут быть получены с использованием одного или более из следующих подшаблонов:

?(шаблон-список)

Соответствует нулю или одному вхождению указанных шаблонов.

*(шаблон-список)

Соответствует нулю или большему количеству вхождений указанных шаблонов.

+(шаблон-список)

Соответствует одному или более вхождений указанных шаблонов.

@(шаблон-список)

Соответствует одному из указанных шаблонов.

!(шаблон-список)

Нет совпадений, кроме одного из указанных шаблонов.

Удаление кавычек

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

Подстановка команд, Арифметические расширение и Процесс замены в bash

Подстановка команд

Подстановка команд позволяет ввод команды, для замены имени команды. Существуют две формы:

$(команда)

или

`команда`

Bash выполняет расширения выполняя команду и замену подстановки команд со стандартным вводом команд, любой символ перевода строки удаляется. Переводы строк не удаляются, но они могут быть удалены во время разбиения на слова. Подстановка команд $(cat файл) может быть заменён эквивалентным, но более быстрым $(< файл).

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

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

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

Арифметические расширение

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

$((выражение))

Старый формат $[выражение] устарел и в следующих версиях bash будет удален. Выражение рассматривается так как если бы оно было заключено в двойные кавычки, но двойные кавычки внутри скобок специально не рассматриваются. Все лексемы в выражении подвергаются расширению параметров, раскрытию строк, подстановке команд и удалению кавчек. Арифметические расширения могут быть вложенными.

Если выражение некорректно, bash выдаст сообщение которое обозначает сбой и замещение не произойдет.

Процесс замены

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

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

Расширения параметров в bash

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

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

${параметр}

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

Если первым символом параметра является восклицательный знак (!), начинается косвенная подстановка. Bash использует значение переменной которая формируется из остальных параметров, таких как имя переменной: затем эта переменная расширяется и это значение используется в остальной части замены, а не само значение параметра. Это называется косвенное расширение. Исключением из этого правила, являются расширения ${!префикс*} и ${!имя[@]}. Восклицательный знак должен следовать непосредственно за левой фигурной скобкой для введения косвенной подстановки.

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

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

${параметр:-слово}

Использует значение по умолчанию. Если параметр не установлен или нулевой, подставляется значение слова которое указано. Иначе подставляется параметр.

${параметр:=слово}

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

${параметр:?слово}

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

${параметр:+слово}

Используется альтернативное значение. Если параметр нулевой или же неустановлен, ничего не заменяется, в ином же случае заменяется на указанное слово.

${параметр:смещение}

${параметр:смещение:длина}

Расширение подстроки. Подставляются символы значения параметра, начиная с указанного смещения и оканчивая указанным значением длины. Если длина не указана, расширение параметра подстроки начинается с символа указанного смещения. В качестве длины и смещения можно задать арифметическое выражение. Если же смещение оценивается как число ниже нуля, то значение используется как смещение из конца значения параметра. Арифметические выражения начиная с «» должны быть отделены пробелом от предыдущих: необходимо отличать от расширений используемых значения по умолчанию. Если длина вычисляется как число меньше нуля, и параметр не является «@», а так же не является индексированным и ассоциативным массивом, то он интерпритируется как смещение с конца значения параметра, вместо числа символов и расширений символов между двумя смещениями. Если параметр «@», в результате длина позиционных параметров начинается со смещения. Если параметр является индексированным массивом, с именем индекса «@» или «*» то результатом является длина элементов массива начиная с ${параметр[смещение]}. Отрицательное смещение, берется относительно максимального индекса указанного массива, на единицу больше. Подстрока расширения применяемая к ассоциативному массиву, приводит к неопределенным результатам. Следует отметить что отрицательное смещение должно быть определено двоеточием, по крайней мере в одном месте, для того чтобы избежать путаницы с расширением «:-». Подстрока индексации начинается с нуля, если позиционные параметры не используются, в этом случае индексация начинается с 1 по умолчанию. Если смещение равно нулю и используются позиционные параметры, $0 префикса списка.

${!префикс*}

${!префикс@}

Имена сообветствующих префиксов. Расширяются в имена переменных, имена которых начинаются с префикса, разделенные первым символом специальной переменной IFS. Когда используется «@» и расширение появляется в двойных кавычках, имя каждой переменной расширяется в отдельное слово.

${!имя[@]}

${!имя[*]}

Список ключей массива. Если имя переменной массива, расширение происходит в список массива индексов(Ключей) назначенных по имени. Если имя не является массивом, расширение происходит до 0, если имя задано и равно нулю в ином случае. Когда используется «@» и расширение появляется в двойных кавычках, каждый ключ расширяется в отдельное слово.

${#параметр}

Длина параметра. Длина символов, значение параметра заманяется. Если параметр «*» или «@» значение заменяется количеством позиционных параметров. Если параметр явялется именем индексного массива «*» или «@» значение заменяется количеством элементов в массиве.

${параметр#слово}

${параметр##слово}

Удаляется шаблон соответствующий префиксу. Слово расширяется для получения шаблона так же, как расширение имен файлов. Если шаблон соответствует начальному значению параметра, то результатом является расширение значения параметра с коротким соответствующим шаблоном »#» или же в длинным соответствующим шаблоном »##» удаляется. Если параметр «@» или «*» операция удаления шаблона применяется к каждому позиционному параметру и подставляется в полученный в результате список. Если параметр представляет собой индексный массив с «@» или «*» операция удаления шаблона применяется к каждому элементу массива по очереди, и подставляется в полученный в результате список.

${параметр%слово}

${параметр%%слово}

Удаляется соответствующий суффикс шаблона. Слово расширяется для получения шаблона так же как расширение имен файлов. Если шаблону соответствует конечная часть значения параметра, то результатом расширения будет значение параметра, в случае с коротким шаблоном »%» и длинным шаблоном »%%» удаляется. Если параметр «@» или «*» операция удаления шаблона применяется к каждому позиционному параметру и подставляется в полученный в результате список. Если параметр представляет собой переменную индексного массива с «@» или «*» операция удаления шаблона применяется к каждому элементу массива по очереди, и расширяется в полученный в результате список.

${параметр/шаблон/строка}

Замещение шаблона. Шаблон расширяется для получения шаблона, так же как расширения имен файлов. Параметр расширяется и самое длинное совпадение шаблона, его значение заменяется строкой. Если шаблон начинается с «/» все совпадения шаблонов заменяются строкой. Обычно заменяется лишь первое совпадение. Если шаблон начинается с «#» он должен соответствовать значению в начале параметра. Если шаблон начинается с «%» он должен соответствовать концу значения параметра. Если строка пустая, то совпадение шаблона будет удалено и «/» следующий шаблон может быть опущен. Если параметр «@» или «*» операция замены применяется к каждому позиционному параметру и подставляется в полученный в результате список. Если параметр представляет собой индексный массив с «@» или «*» операция замены применяется к каждому элементу массива по очереди и подставляется в полученный в результате список.

${параметр^шаблон}

${параметр^^шаблон}

${параметр,шаблон}

${параметр,,шаблон}

Случайное изменение. Это расширение изменяет случайным образом буквы в параметре. Шаблон расширяется для получения шаблона так же как расширение имен файлов. Оператор «^» преобразует прописные буквы соответствующего шаблона в верхний регистр, оператор «,» преобразует соответствующие заглавные буквы в нижний регистр. «^^» и «,,» расширения преобразовывают каждый соответствующий символ в расширенное значение, «^» и «,» расширения соответствуют и преобразовывают только первый символ в расширенном значении. Если шаблон не указан, он рассматривается как «?» который соответствует каждому символу. Если параметр «@» или «*» операция случайной модификации применяется к каждому позиционному параметру и подставляется в полученный в результате список. Если параметр представляет собой индексный массив с «@» или «*» операция случайной модификации применяется к каждому элементу массива по очереди и подставляется в полученный в результате список.

Расширения фигурных скобок и расширения тильды

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

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

Фигурные скобки расширения могут вкладываться. Результаты каждой расширенной строки не сортируются; порядок сохраняется слева на право. Для примера, a{b,c,d}e расширяется в ‘abe ace ade’.

Выражение последовательности принимает вид {x..y[..incr]}, где x и y являются любо целые или отдельные символы, и incr, дополнительное прирашение является целым числом. Когда подставляются целые числа, выражение расширяется с каждым номером между x и y, включительно. Подставление целых чисел может иметь префикс 0, чтобы заставить каждую часть иметь одинаковую ширину. Когда x или y начинается с нуля, оболочка пытается заставить все генерируемые термины содержать одинаковое количество цифр, при необходимости происходит заполнение нулями. Когда подставляются знаки, в выражении расширяется каждый символ лексикографически между x и y, включительно. Следует отметить, что х и у должны быть одного типа. Когда подставляется приращение, оно используется как разность между каждым термином. По умолчанию приращение равно 1 или -1, по мере необходимости.

Фигурные скобки выполняются перед любыми иными расширениями, все специальные символы иных расширений сохраняются в результате. Это строго текстуально. Bash не применяет никакой синтаксической интерпретации контекста расширения или текста, заключенного в фигурные скобки. Правильно сформированные фигурные скобки, должны содержать кавычки, и открывающую, а так же закрывающую фигурные скобки, и по крайней мере одну неназванную запятую или допустимое выражение последовательности. Любые некорректные скобки, остаются неизменными. «{» или «,», может быть отменено обратной косой чертой, чтобы предотвратить его считаться частью из скобки выражения. Чтобы избежать конфликтов с параметром расширения, строка «${» не считается частью расширения фигурных скобок. Эта конструкция используется для краткости, когда общий префикс строк, которые будут созданы больше, чем в предыдущем примере:

mkdir /usr/local/src/bash/{old,new,dist,bugs}

или

chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}

Фигурные скобки вносят некоторую несовместимость с устаревшими версиями sh. sh не относится к открытию или закрытию фигурных скобок, особенно когда они появляются как часть слова и сохраняет их в выводе. Bash удаляет скобки из слов как следствие подстановка фигурных скобок. Например слово введеное в sh как file{1,2} отображается одинаково в выводе. Тоже слово выводится как file1 file2 после расширения в Bash. Если необходима полная совместимость с sh, bash желательно запускать с опцией +B или отключить фигурное расширение скобок с опцией +B команды set.

Расширения тильды

Если слово начинается с символа тильды заключенного в одиночные кавычки (‘~’), все символы символы предшествующие первой черте кавычки, или все символы если нет косой черты перед кавычкой, считается тильдой префикса. Если ни один из символов в Тильда-префикс не указаны, символы в тильда-префикс после тильды рассматриваются как возможное логин имя. Если регистрационное имя является пустой строкой, тильда заменяется на значение shell параметров HOME. Если HOME не задана, в домашнем каталоге пользователя, shell замещается на каталог пользователя который выполняет процесс командного интерпретатора. В противном случае, тильда-префикс заменяется на домашний каталог, связанный с указанным логином входа.

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

Если логин пользователя недействителен, или расширение тильды не получается, слово остается неизменным.

Каждая назначенная переменная проверяется на наличие незамаскированных тильда-префиксов сразу после «:» или «=». В этих случаях расширение тильды, так же выполняется. Следовательно, можно использовать имена файлов с тильдами, в присваиваниях переменных PATH, MAILPATH и CDPATH, и shell выполнит необходимое расширение.

Расширения в bash

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

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

В системах которые способны это поддерживать, есть дополнительные доступные расширения: процесс замены.

Количество слов расширения можно изменить только расширением фигурных скобок, разбиением слов и подстановкой имен файлов; иные же расширения расширяют одно, слово в одно слово. Единственным исключением из этого правила, является расширение «$@» и «${имя[@]}«, как я описывал в параметрах выше.

Массивы bash

Bash поддерживает одномерные индексированные и ассоциативные массивы переменных. Любая переменная может быть использована как индексированный массив, явно объявить массив можно при помощи встроенной команды «declare». Здесь нет ограничений на максимальный размер массива, единственное требование которое есть это то что элементы массива имеют индексы и значения индексов идет подряд. Индексированные массивы используют целые числа и начинаются с нуля; ассоциативные массивы используют произвольные строки.

Индексированные массивы создаются автоматически, если присваиваются любой переменной используя синтаксис

имя массива[индекс] = значение

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

declare -a имя массива

Так же принимается с игнорированием индекса

declare -a имя [индекс]

Ассоциативные массивы создаются при помощи

declare -A name

Атрибуты могут быть определены для массива переменой с помощью встроенных команд declare и readonly. Каждый атрибут применяется ко всем частям массива.

Массивы назначаются с использованием соединений присвоения имя=(значение1 … значениеN) где каждое значение имеет вид [индекс]=строка. Индекс не обязателен. В том случае если он указан, то он используется в инструкции присваивания, в ином же случае в качестве индекса используется значение индекса которое было назначено, плюс один. Если индекс не указывается, индексация начинается с нуля.

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

имя[индекс]=значение

На любой элемент массива можно ссылаться с помощью ${имя[индекс]}. Фигурные скобки необходимы для того чтобы избежать конфликтов с путями расширений. Если в качестве индекса стоит «@» или «*», то слово значит все части названия. Эти индексы отличаются лишь тогда, когда это слово заключено в двойные кавычки. Если слово заключено в двойные кавычки, ${имя[*]} заменяется одним словом со значением каждого элемента массива, разделенных первым символом специальной переменной IFS, и ${имя[@]} расширяет каждый элемент имени отдельным словом. Когда нет составляющих массива, ${имя[@]} заменяется пустой строкой. Если расширение двойных кавычек происходит в пределах слова, расширение первого параметра объеденяется с начальной частью исходного слова, а расширение последнего параметра вместе с последней частью исходного слова. Это аналогично расширению специальных параметров «@» и «*» о них я писал немного раньше. ${#имя[индекс]} заменяется длиной ${имя[индекс]}. Если в качестве индекса «*» или «@», расширением является количество элементов в массиве. Ссылка на переменную массива без индекса, эквивалентна ссылке на массив с индексом 0.

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

Встроенная команда unset используется для уничтожения массивов. unset имя[индекс] уничтожает элемент массива с указанным индексом. Необходимо соблюдать осторожность, чтобы избежать нежелательных побочных эффектов, вызванных путями расширения. unset имя, где имя является массивом, или unset имя[индекс], где в качестве индекса указан «*» или «@», удаляется весь массив.

Встроенные команды declare, local и readonly, принимают -a option для указания индексированного массива, и -A option чтобы указать ассоциативный массив. Если подставляются оба варианта, -A имеет приоритет. Встроенная команда read принимает -a option, назначает список слов, прочитанных из стандартного ввода в массив. Встроенные команды set и declare, отображают значения массива таким образом, что позволяет им быть повторно использованными в качестве задания.