$ test=false
$ echo $test
false
$ ((!test))
((test=false))
$ echo $?
1
$ echo $test
0
Почему test
сейчас 0? Я не понимаю, где и почему ((
назначается test
или почему оно печатается ((test=false))
. Это происходит только при написании команд вручную на терминале; при выполнении тех же команд в качестве теста сценария остается значение «false».
Также обратите внимание, что ((!test))
не будет работать в скрипте. Вы используете расширение истории, но история в скриптах по умолчанию не включена.
@Barmar Я могу воспроизвести то же поведение, что и OP, без false=0
. Какую версию вы используете? Я использую 5.0.
Я тестировал в bash 5.1.4
@EdMorton Могу поспорить, они думали, что false
— это именованная константа, например false
в JS, где !false
→ true
.
Во-первых, test
и false
— это также имена встроенных функций, которые здесь не имеют значения, поэтому для ясности я собираюсь изменить их на foo
и bar
.
$ foo=bar
$ echo $foo
bar
!foo
— это расширение истории, а команда сопоставления — foo=bar
.
$ echo !foo
echo foo=bar
foo=bar
$ ((!foo))
((foo=bar))
$ echo $?
1
В арифметическом контексте строка bar
рассматривается как имя переменной, но эта переменная не определена, поэтому она оценивается как 0
. Отсюда foo=0
.
$ echo $foo
0
Расширение истории актуально только в интерактивной оболочке — оно отключено в скрипте — поэтому, не зная контекста выполнения, трудно сказать, уместно ли оно здесь.
@Чарльз, что ты имеешь в виду? Видение поведения ОП происходит только из-за расширения истории.
Ах, пропустил, что следующая строка была результатом расширения, а не кодом, вызванным вручную. Да, вы абсолютно правы.
P.S. Моя оболочка настроена на раскрашивание команды, которую я набираю (путем добавления завершающей escape-последовательности в PS1 '\[\e[36m\]'
с терминатором в PS0 '\e[m'
), а также раскрашивает предварительный просмотр расширения истории и различные другие вещи. Полезно в этом случае :) но это кажется хакерским, так что ИДК, если бы я рекомендовал это.
Когда я это делаю
((!test))
, я получаю сообщение об ошибке:bash: false: unbound variable
. Возможно ли, что вы сделалиfalse=0
раньше?