Экспансия – процесс анализа командной строки с целью нахождения в ней специальных обозначений (выражений) и подстановки на их место соответствующих значений.
Для просмотра результата экспансии набранной в данный момент строки можно нажать (<Esc>, <Ctrl>-<e>) , а затем можно вернуть на место прежнюю строку через undo (<Ctrl>-<->).
Порядок экспансии таков.
1. {}-экспансия (bash specific). Создает преамбулы и постамбулы:
${n} – если цифр больше одной, номер параметра надо брать в {};
${n:-default} – если параметр или переменная пусты, подставить default;
${var:=default} – только для переменных: если переменная пуста, присвоить ей default и подставить это значение;
${n:?message} – если пусто, выдать сообщение message и прекратить работу;
${n:+value} – если пусто, оставить пустым, а иначе подставить value; аналог в Си: 'flag ? string : "" ';
$# – число аргументов, в отличие от Си $0 не считается;
${#n} – длина параметра или переменной;
${n#pattern} – отрезать начало, совпадающее с паттерн (shortest matching);
${n##pattern} – отрезать начало, совпадающее с паттерн (longest matching);
${n%pattern} – отрезать конец, совпадающий с паттерн (shortest matching);
${n%%pattern} – отрезать конец, совпадающий с паттерн (longest matching). Например, конструкция вида:
set $1="--file=a.txt"
echo ${1#--file=}
выведет
a.txt ;
$*, $@. Если надо при передаче всех аргументов сохранить исходные кавычки, используется "$@" (именно в двойных кавычках!). А "$*" передают все аргументы как один, тоже в кавычках. Без кавычек $* $@ эквивалентны и не годятся для передачи аргументов в кавычках;
$? – код выхода последней команды, в т. ч. встроенной (похоже на errorlevel в DOS);
$$ – PID, очень полезно для создания временных файлов с уникальными именами:
tmpfile1=tmp1$$,
tmpfile2=tmp2$$;
$! ??? – Expands to the process ID of the most recently executed background (asynchronous) command;
$_ – последний аргумент предыдущей команды;
$- – флаги для команды set.
4. Командная подстановка. Варианты:
$( ) и ` ` (обратные кавычки). Заменяются на вывод команды без символов новой строки
`команда`
– старый стиль, обрабатываются внутренние backslashes. Чтобы сделать вложение, внутри надо писать:
`команда1 \`команда2\`` .
$(команда)
– новый стиль (специфика bash), все, что находится внутри скобок, без обработки рассматривается как команда. Чтобы сделать вложение, надо писать:
<SPAN CLASS="EXAMPLE0">
$(command1 $(command2)) .
</SPAN>
5. Арифметическая подстановка:
$(( )) или $[ ]
Есть, среди прочих, операции << и >>.
Переменные можно использовать как с " $" , так и без.
Есть все виды присваивания:
= *= /= %= += -= <<= >>= &= ^= |=
«Понимает» префиксы 0 и 0x.
n # – префикс, указывающий любую [позиционную] систему счисления.
6. Подстановка процесса (специфика bash). Возможна на системах, поддерживающих named pipelines(FIFOs):
>(команды)
– отправить вывод команды в некоторый файл и передать имя этого файла как аргумент другой команде.
<(команды)
– отправить вывод команд в файл и подставить имя этого файла.
Пример. Сравнить выводы программ newprogram и oldprogram:
diff <(newprogram) <(oldprogram)
Еще пример. Загрузить вывод команды ls в редактор vi:
vi <(ls)
Следует заметить, что выполнение именно этой команды соответствует ожиданиям, тогда как команда:
ls | vi
приведет или к сообщению об ошибке, или к другим неожиданным последствиям.
7. path-экспансия. Обрабатывает ?, *, [ list ] и [^ list ] в именах файлов:
* – все файлы, кроме начинающихся на "."
.* – файлы, начинающиеся на "."
Чтобы сделать шаблон, которому бы соответствовали все файлы, в том числе начинающиеся на ".", но исключая файлы "." и ".." , надо использовать сразу три шаблона:
.[^.]* .??* * ,
потому что:
".[^.]*" – включает все файлы с одной точкой в начале (но не с двумя), в именах которых на втором месте не стоит ".";
".??" – включает все файлы, состоящие из точки и еще двух знаков, что позволит исключить файл "..";
"*" – включает все файлы, не начинающиеся с "." .
8. Удаление кавычек. В конце экспансии все кавычки, кроме экранированных ( \"), удаляются.