Рейтинг:5

Оператор приращения не работает с переменной, если для переменной установлено значение 0

флаг br

Увеличение переменной вар работает в bash, когда заключен в двойные скобки, например ((переменная++)). Но я обнаружил, что он терпит неудачу, если для переменной заранее установлено значение 0, например переменная = 0.

$ а = 0
$ ((a++)) && echo "команда выполнена успешно" || эхо "команда не удалась"
команда не удалась

$ а = 1
$ ((a++)) && echo "команда выполнена успешно" || эхо "команда не удалась"
команда выполнена успешно

Может кто-нибудь объяснить такое поведение?

Среда:

Я использую gnome-терминал на Ubuntu Desktop 18.04.5 LTS.

pLumo avatar
флаг in
Я думаю, что вы не должны на самом деле знать о статусе выхода `((`, чтобы узнать, сработала ли команда.. *>> «Если результат выражения равен 0, возвращаемый код состояния выхода будет 1 или «false» , в то время как код состояния выхода, возвращаемый выражением с ненулевым значением, будет 0 или «true». панцирь-2))
wjandrea avatar
флаг cn
Примечание: существует несколько способов [увеличить переменную в Bash](/q/385528/301745). Вероятно, наиболее идиоматично сначала явно указать целое число: `declare -i a=0`, а затем `a+=1`.
ilkkachu avatar
флаг co
@pLumo, неправильный не статус выхода, а предположения пользователей (ваши тоже). Он работает точно так же, как определен пост-инкремент, и точно так же, как, например, в. C. Хотя вы правы в том, что вы не можете использовать статус выхода `(( .. ))`, чтобы увидеть, работает ли он, поскольку синтаксическая ошибка также приводит к выходу со статусом 1 (а не, например, 2, как `[` и `[[` делают)
Saad Abdul Majid avatar
флаг br
@pLumo, меня беспокоит код состояния выхода, потому что скрипт использует «ловушку ... ERR», и эта строка провоцирует его. На данный момент я избегал этого сценария, используя предварительное приращение, поскольку мое базовое значение равно 0 для `var`. Но это решение специфично для моего варианта использования. Возможно, мне следует поискать способ обойти «ловушку» для таких/выбранных утверждений.
Рейтинг:10
флаг cn

С кредитом отсюда: https://unix.stackexchange.com/questions/146773/why-bash-increment-n-0n-return-error

Возвращаемое значение (( выражение )) не указывает на статус ошибки, но из справочной страницы bash:

((выражение)) Выражение оценивается в соответствии с правилами, описанными ниже в разделе АРИФМЕТИЧЕСКОЕ ВЫЧИСЛЕНИЕ. Если значение выражения ненулевой, статус возврата равен 0; в противном случае статус возврата равен 1. Это в точности эквивалентно выражению let.

В ((а++))вы делаете приращение поста. Значение а является 0 так 1 возвращается, после чего увеличивается.

Сравнивать

$ отключить
$ ((а++)) ; эхо код выхода: $? а: $а
Код выхода: 1 а: 1

против

$ отключить
$ ((++а)) ; эхо код выхода: $? а: $а
Код выхода: 0 a: 1

Предварительное приращение, поэтому а стал 1 и 0 возвращается.

wizzwizz4 avatar
флаг de
Технически приращение происходит до возврата; однако возвращаемое значение является значением, полученным до приращения.
Рейтинг:5
флаг jp

Это работает для меня (в бить в убунту),

$ а = 0
$ эхо $((а++))
0
$ эхо $((а++))
1
$ эхо $((а++))
2
$ эхо $((а++))
3
$ эхо $ а
4

Обратите внимание на разницу с

$ а = 0
$ эхо $((++а))
1
$ эхо $((++а))
2
$ эхо $((++а))
3
$ эхо $ а
3
pLumo avatar
флаг in
проверьте `эхо $?`.
sudodus avatar
флаг jp
@pLumo, echo $((a++)) печатает перед обновлением, echo $((++a)) печатает после обновления.
bac0n avatar
флаг cn
Арифметическое расширение не выдает статус выхода не видит подключение?

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.