Современная и лучшая альтернатива — синтаксическая конструкция $((...))
. Поместив в эту конструкцию выражение, которое вы хотите вычислить, вы можете выполнить простые арифметические операции гораздо эффективнее.
#!/bin/sh
х=0
while [ "$х" -ne 10 ]; do
echo $х
х=$(($x+1))
done
exit 0
Примечание
Обратите внимание на тонкое отличие приведенной подстановки от команды х=$(...)
. Двойные скобки применяются для подстановки значений в арифметические выражения. Вариант с одиночными скобками, показанный ранее, используется для выполнения команд и перехвата их вывода.
Подстановка значений параметров
Вы уже видели простейший вариант присваивания параметра и подстановки значения параметра:
foo=fredecho $foo
Проблема возникает, когда вы хотите вставить дополнительные символы в конец значения переменной. Предположим, что вы хотите написать короткий сценарий обработки файлов 1_tmp и 2_tmp. Вы могли бы написать следующие строки:
#!/bin/sh
for i in 1 2 do
my_secret_process $i_tmp
done
Но в каждом проходе цикла вы получите следующее сообщение:
my_secret_process: too few arguments
В чем ошибка?
Проблема заключается в том, что командная оболочка попыталась подставить значение переменной $i_tmp
, которая не существует. Оболочка не считает это ошибкой; она просто не делает никакой подстановки, поэтому в сценарий my_secret_process не передаются никакие параметры. Для обеспечения подстановки в переменную части ее значения $i
необходимо i
заключить в фигурные скобки следующим образом:
#!/bin/sh
for i in 1 2 do
my_secret_process ${i}_tmp
done
В каждом проходе цикла вместо ${i}
подставляется значение i
и получаются реальные имена файлов. Вы подставляете значение параметра в строку.
В командной оболочке можно выполнять разнообразные виды подстановок. Часто они помогают найти красивое решение задач, требующих обработки многих параметров. Самые распространенные виды подстановок значений параметров приведены в табл. 2.18.
Таблица 2.18
Шаблон подстановки параметра |
Описание |
${ парам :- значение по умолчанию } |
Если у парам нет значения, ему присваивается значение по умолчанию |
${# парам } |
Задается длина парам |
${ парам % строка } |
От конца значения парам отбрасывается наименьшая порция, совпадающая со строкой , и возвращается остальная часть значения |
${ парам %% строка } |
От конца значения парам отбрасывается наибольшая порция, совпадающая со строкой , и возвращается остальная часть значения |
${ парам # строка } |
От начала значения парам отбрасывается наименьшая порция, совпадающая со строкой , и возвращается остальная часть значения |
${ парам ## строка } |
От начала значения парам отбрасывается наибольшая порция, совпадающая со строкой , и возвращается остальная часть значения |
Эти подстановки очень полезны при работе со строками. Последние четыре варианта, удаляющие части строк, особенно пригодятся при обработке имен файлов и путей к ним, как показано в упражнении 2.18.
В приведенном далее сценарии показано применение шаблонов при подстановках значений параметров.
#!/bin/sh
unset foo
echo ${foo:-bar}
foo=fud
echo ${foo:-bar}
foo=/usr/bin/X11/startx
echo ${foo#*/}
echo ${foo##*/}
bar=/usr/local/etc/local/networks
echo ${bar%local*}
echo ${bar%%local*}
exit 0
У этого сценария следующий вывод:
bar
fud
usr/bin/X11/startx
startx
/usr/local/etc/usr
Как это работает
Первая подстановка ${foo:-bar}
дает значение bar
, поскольку у foo
нет значения в момент выполнения команды. Переменная foo
остается неизменной, т.е. она остается незаданной.
Примечание
Подстановка ${foo:=bar}
установила бы значение переменной $foo
. Этот строковый шаблон устанавливает, что переменная foo
существует и не равна null
. Если значение переменной не равно null
, оператор возвращает ее значение, в противном случае вместо этого переменной foo
присваивается значение bar
.
Читать дальше