Ответы:
Все они имеют дело с арифметикой, но по-разному, и переменная создается с помощью различных средств. Некоторые из них относятся только к bashоболочкам, а другие нет.
$((...))называется арифметическое расширение , которое является типичным bashи kshоболочек. Это позволяет делать простую целочисленную арифметику, но без всякой вещи с плавающей точкой. Результат выражения заменяет выражение, как echo $((1+1))станетecho 2((...))называется арифметической оценкой и может использоваться как часть if ((...)); thenили while ((...)) ; doутверждения. Расширение арифметического расширения $((..))заменяет вывод операции и может использоваться для назначения переменных, как в, i=$((i+1))но не может использоваться в условных выражениях.$[...] старый синтаксис для арифметического расширения, который устарел. Смотрите также . Скорее всего, это сохранилось, чтобы старые bashсценарии не ломались. Это не сработало ksh93, поэтому я предполагаю, что этот синтаксис специфичен для bash. ПРИМЕЧАНИЕ : пробелы здесь очень важны; не путайте $[1+1]с такими вещами, как [ $a -eq $b ]. С [пробелами называется testкоманда, и вы обычно видите это в части принятия решений. Это очень отличается по поведению и цели.letявляется ключевым словом bashand, kshкоторое позволяет создавать переменные с простой арифметической оценкой. Если вы попытаетесь назначить строку там, как let a="hello world"вы получите синтаксическую ошибку. Работает в bashа ksh93.$(...)является подстановкой команды, где вы буквально берете выходные данные команды и присваиваете переменную. Ваша команда здесь expr, которая принимает позиционные аргументы, например expr arg1 arg2 arg3, пробелы важны. Это что-то вроде небольшого калькулятора командной строки для целочисленной арифметики, плюс некоторые вещи типа true / false и regex. Это нейтральная для оболочки команда.Стоит также отметить, что арифметическое расширение и подстановка команд определены стандартом POSIX , а так letи $[...]нет.
letКоманда выполняет арифметическую оценку и является встроенной в оболочку.
Запустите эту команду, и вы ничего не получите (только оценки):
let 1+2$(( ))используется для выполнения арифметического расширения : читайте здесь
Запустите этот, и вы получите ошибку (из-за расширения):
$((1+2))$[ ] старый синтаксис для арифметического расширения:
Старый формат $ [expression] устарел и будет удален в следующей версии bash. Bash Man Page
expr это бинарная команда, если вы хотите сделать арифметическое раскрытие в подстановке команд, вы можете использовать ее:
echo $(expr 1 + 2)
echo `expr 1 + 2`Поскольку в некоторых ответах выше конкретно упоминается ksh93, стоит отметить, что он может выполнять математические операции с плавающей запятой, например:
$ print $((1.0/3))
0.333333333333333333
Вы можете контролировать точность вывода с помощью printf, например:
$ printf "%.4f\n" $((1.0/3))
0.3333
Как минимум один аргумент должен быть указан как число с плавающей точкой, как указано выше. Если оба заданы как целые числа, то выполняется только целочисленная математика, например:
$ print $((1/3))
0
Это может быть полезно, когда вам нужна математика с плавающей точкой в сценарии оболочки, поскольку вы можете избежать вызова внешней команды.
zshответ . Поскольку kshи bashони больше похожи друг на друга (в целом), чем на что-либо zsh, мне кажется, что kh93основанный на этом вопрос ответ может быть весьма полезным.
((...))фактически может использоваться для заданийbash,kshаzsh:n=10; ((n+=10)); echo $nпечатает 20 и((x=1)); echo $xпечатает 1.