Почему в этом случае составная команда (( присваивает значение переменной?

$ test=false
$ echo $test
false
$ ((!test))
((test=false))
$ echo $?
1
$ echo $test
0

Почему test сейчас 0? Я не понимаю, где и почему (( назначается test или почему оно печатается ((test=false)). Это происходит только при написании команд вручную на терминале; при выполнении тех же команд в качестве теста сценария остается значение «false».

Когда я это делаю ((!test)), я получаю сообщение об ошибке: bash: false: unbound variable. Возможно ли, что вы сделали false=0 раньше?

Barmar 05.09.2024 21:49

Также обратите внимание, что ((!test)) не будет работать в скрипте. Вы используете расширение истории, но история в скриптах по умолчанию не включена.

Barmar 05.09.2024 21:49

@Barmar Я могу воспроизвести то же поведение, что и OP, без false=0. Какую версию вы используете? Я использую 5.0.

wjandrea 05.09.2024 21:59

Я тестировал в bash 5.1.4

Barmar 05.09.2024 22:10

@EdMorton Могу поспорить, они думали, что false — это именованная константа, например false в JS, где !falsetrue.

wjandrea 05.09.2024 22:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, 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

Расширение истории актуально только в интерактивной оболочке — оно отключено в скрипте — поэтому, не зная контекста выполнения, трудно сказать, уместно ли оно здесь.

Charles Duffy 05.09.2024 22:28

@Чарльз, что ты имеешь в виду? Видение поведения ОП происходит только из-за расширения истории.

wjandrea 05.09.2024 22:38

Ах, пропустил, что следующая строка была результатом расширения, а не кодом, вызванным вручную. Да, вы абсолютно правы.

Charles Duffy 05.09.2024 22:44

P.S. Моя оболочка настроена на раскрашивание команды, которую я набираю (путем добавления завершающей escape-последовательности в PS1 '\[\e[36m\]' с терминатором в PS0 '\e[m'), а также раскрашивает предварительный просмотр расширения истории и различные другие вещи. Полезно в этом случае :) но это кажется хакерским, так что ИДК, если бы я рекомендовал это.

wjandrea 05.09.2024 22:54

Другие вопросы по теме

Похожие вопросы

Как использовать цикл bash for для awk для печати строки FPAT, найденной в переменной в кавычках
Bash printf не работает для чисел с плавающей запятой
Bash с использованием сценария Expect выдает ошибку при вызове ssh
Почему моя программа, запущенная из сценария bash, останавливается, когда сценарий находится в фоновом режиме, но только тогда, когда он получает стандартный ввод из именованного канала?
Когда grep ищет шаблоны в файле с кавычками и/или без кавычек в bash?
Как извлечь столбцы из файла CSV, обработать и создать файл CSV на основе результата извлечения и обработки?
Скрипт Bash, который принимает несколько аргументов пути и проверяет, можно ли там успешно создать файлы
Почему bash не завершает выполнение сценария после ошибки внутри скобок?
Как запустить эмулятор терминала во время работы оболочки?
Как мне отслеживать и уничтожать все процессы, порожденные запуском сценария, не зная имен подпроцессов?