expr
не похоже на круглые скобки (используется в математике для явного приоритета оператора):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Как выразить приоритет оператора в bash?
shell
quoting
arithmetic
expr
Николас Рауль
источник
источник
let
. Он не является более стандартным или переносимым, чем(( a = 3 * (2 + 1) ))
(оба полученыksh
и доступны только в ksh, bash и zsh), и его менее разборчиво или легко процитировать. Используйте,a=$((3 * (2 + 1)))
чтобы быть портативным.((a = 3 * (2 + 1) ))
, другая для переносимостиa=$((3 * (2 + 1)))
), так что это не примечание против вас или вашего ответа, а против того, чтобы он был выбранным ответом и лучший бомбардир.a=1 $[a+2]
илиa=1 b=2 $[a+b]
. Их причина, чтобы избежать этого синтаксиса?Вместо этого вы можете использовать арифметическое расширение.
По моему личному мнению, это выглядит немного лучше, чем использование
expr
.Из
man bash
источник
Нет смысла использовать
expr
арифметику в современных оболочках.POSIX определяет
$((...))
оператор расширения. Таким образом, вы можете использовать это во всех POSIX-совместимых оболочках (sh
всех современных Unix-лайков, dash, bash, yash, mksh, zsh, posh, ksh ...).ksh
также представилlet
встроенную функцию, которой передается то же самое арифметическое выражение, не расширяется во что-то, но возвращается состояние выхода, основанное на том, разрешает ли выражение значение 0 или нет, как вexpr
:Однако, поскольку цитирование делает его неловким и не очень разборчивым (не в такой же степени, как,
expr
конечно),ksh
также введена((...))
альтернативная форма:который намного более разборчивый и должен использоваться вместо этого.
let
и((...))
доступны только вksh
,zsh
иbash
.$((...))
Синтаксис должен быть предпочтительным , если портативность для других оболочек необходима,expr
требуется только для предварительного POSIX Борн-подобных оболочек (обычно Bourne оболочки или ранних версий Almquist оболочки).На фронте не-Борна есть несколько оболочек со встроенным арифметическим оператором:
csh
/tcsh
(фактически первая оболочка Unix со встроенной арифметической оценкой):akanga
(на основанииrc
)Как следует из истории, оригинальная версия оболочки Almquist, опубликованная в usenet в 1989 году, имела
expr
встроенную функцию (фактически объединенную сtest
), но позже была удалена.источник
: $((a = a*2))
?$((...))
такие как zsh, ksh93 или yash.expr
это внешняя команда, это не специальный синтаксис оболочки. Поэтому, если вы хотитеexpr
видеть специальные символы оболочки, вам нужно защитить их от разбора оболочки, заключив их в кавычки. Кроме того,expr
необходимо, чтобы каждый номер и оператор передавались как отдельный параметр. Таким образом:Если вы не работаете над антикварной системой Unix 1970-х или 1980-х годов, причин для использования очень мало
expr
. В старые времена в оболочках не было встроенного способа выполнения арифметики, иexpr
вместо этого приходилось вызывать утилиту. Все оболочки POSIX имеют встроенную арифметику через синтаксис арифметического расширения .Конструкция
$((…))
расширяется до результата арифметического выражения (записанного в десятичной форме). Bash, как и большинство оболочек, поддерживает только целочисленную арифметику по модулю 2 64 (или по модулю 2 32 для более старых версий bash и некоторых других оболочек на 32-разрядных машинах).Bash предлагает дополнительный удобный синтаксис, когда вы хотите выполнить присваивания или проверить, равно ли выражение 0, но не заботитесь о результате. Эта конструкция также существует в ksh и zsh, но не в простой sh.
В дополнение к целочисленной арифметике,
expr
предлагает несколько функций для работы со строками. К ним также относятся функции оболочек POSIX, за исключением одного:expr STRING : REGEXP
проверяет, соответствует ли строка указанному регулярному выражению. Оболочка POSIX не может сделать это без внешних инструментов, но bash может с[[ STRING =~ REGEXP ]]
(с другим синтаксисом регулярных выражений -expr
это классический инструмент и использует BRE, bash использует ERE).Если вы не поддерживаете сценарии, которые работают на 20-летних системах, вам не нужно знать, что
expr
когда-либо существовало. Используйте арифметику оболочки.источник
expr foo : '\(.\)'
также делает извлечение текста.bash
«SBASH_REMATCH
достигает что - то подобное. Он также выполняет сравнение строк, чего[
не делает POSIX (хотя можно представить способы его использованияsort
).Используйте скобки с кавычками:
Кавычки не позволяют bash интерпретировать скобки как синтаксис bash.
источник
expr
командной строке должны быть разделены пробелами; так; например,expr 3 "*" "(2" "+" "1)"
не будет работать . (Кроме того, кстати, вам, вероятно, не нужно цитировать+
.)while
и[[
они синтаксис так. Если бы они были ключевыми словами, они не были бы интерпретированы как таковые в аргументах команды. Вам нужны кавычки, чтобы bash не анализировал их, а вместо этого видел строковый литерал.Если у вас есть до н.
источник