Пара команд, связанных с арифметикой, Dash, POSIX shell, sh, Increment

17

При увеличении переменной до / после, в POSIX Shell, в чем разница между этими двумя примерами. Кажется, что они будут иметь те же последствия, но будут ли они использоваться по-другому? Когда бы вы предпочли одно другому?

X=$((X+1))

: $((X=X+1))
Дж. М. Беккер
источник

Ответы:

18

В вашем первом примере $((X+1))вычисляется выражение X + 1 и расширяется до результата, который затем присваивается переменной.

Во втором примере $((X=X+1))увеличивается Xна единицу ( $((X++))также допустимо и короче, но не обязательно поддерживается оболочкой), а затем расширяется до нового значения $X, которое является первым аргументом для пустой команды :. Команда null игнорирует свои аргументы, и результат отбрасывается (с побочными эффектами).

Я бы лично предпочел первую форму по трем (относительно субъективным) причинам:

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

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

X=$((X+1)) /usr/local/bin/something

Вы должны использовать вторую форму, чтобы добавить оценку к аргументам напрямую:

ls -la "file-$((X++))"   # or ...
ls -la "file-$((X=X+1))" # for better compatibility

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

Алексиос
источник