Bash: условный оператор вызывает «неожиданный конец файла» в macOS

Когда я использую следующий простой скрипт в оболочке bash на macOS (Sonoma 14.4.1), я получаю «Синтаксическая ошибка: неожиданный конец файла».

#!/bin/bash
echo "Hello"
echo "$SHELL"
echo "$BASH_VERSION"
/bin/bash --version

if [[ -n "foobar" ]]; then
  echo "Ok"
fi

echo "Bye"

Если я вычеркну оператор source (строки 7–9), он будет вести себя так, как ожидалось. В Linux (CentOS 7) он (с оператором if) выдает ожидаемый результат с «ОК».

Я использую окончания строк Unix (LF).

Результат macOS:

$ source bash-if-trouble.sh 
Hello
/bin/bash
3.2.57(1)-release
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23)
Copyright (C) 2007 Free Software Foundation, Inc.
-bash: bash-if-trouble.sh: line 12: syntax error: unexpected end of file

if дает аналогичный результат.

Результат CentOS7, который также ожидается в macOS (конечно, с учетом сведений о версии):

$ source bash-if-trouble.sh 
Hello
/bin/bash
4.2.46(2)-release
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Ok
Bye

По предложению @Philippe:

$ od -a bash-if-trouble.sh 
0000000    #   !   /   b   i   n   /   b   a   s   h  nl   e   c   h   o
0000020   sp   "   H   e   l   l   o   "  nl   e   c   h   o  sp   "   $
0000040    S   H   E   L   L   "  nl   e   c   h   o  sp   "   $   B   A
0000060    S   H   _   V   E   R   S   I   O   N   "  nl   /   b   i   n
0000100    /   b   a   s   h  sp   -   -   v   e   r   s   i   o   n  nl
0000120   nl   i   f  sp   [   [  sp   -   n  sp   "   f   o   o   b   a
0000140    r   "  sp   ]   ]   ;  sp   t   h   e   n  nl  sp  sp   e   c
0000160    h   o  sp   "   O   k   "  nl   f   i  nl  nl   e   c   h   o
0000200   sp   "   B   y   e   "  nl                                    
0000207

У меня работает в crufy bash 3.2, поставляемом с MacOS, в bash 5.2 и даже в zsh.

Robert 04.05.2024 00:03

Можете ли вы опубликовать результат команды od -a your-script?

Philippe 04.05.2024 00:17

Я могу воспроизвести это, если строка fi заканчивается возвратом каретки. Исправьте скрипт с помощью dos2unix

Barmar 04.05.2024 00:17

Я почти уверен, что в сценарии нет случайных символов CR. 1) Я написал сценарий в той же системе MacOS. 2) grep ^M bash-if-trouble.sh не производит результата. 3) Мой редактор указывает окончания строк LF.

Curtis G. 04.05.2024 02:34

Что печатает /bin/bash --version?

John Bollinger 04.05.2024 03:06

@CurtisG — ваши комментарии по поводу вывода od -a bash-if-trouble.sh лучше всего будут представлены в вопросе — вы сможете отформатировать информацию для удобства чтения.

Jonathan Leffler 04.05.2024 07:26

Можешь попробовать source ./bash-if-trouble.sh ?

Philippe 04.05.2024 10:28

Пожалуйста, добавьте echo "$BASH_VERSION" в свой скрипт, а затем добавьте этот вывод в свой вопрос, чтобы мы могли видеть, какую версию bash вы используете при исходном коде сценария. Шебанг вверху, #!/bin/bash будет игнорироваться при его получении, кстати, код будет запускаться в любой оболочке, которую вы запускаете при исходном файле. Кроме того, echo "$SHELL" просто сообщает нам оболочку по умолчанию, но не сообщает, какая оболочка запущена в данный момент.

Ed Morton 04.05.2024 15:42

Спасибо Филиппу, Джону Боллинджеру, Джонатану Леффлеру и Эду Мортону за предложения. Я соответствующим образом обновил тело вопроса.

Curtis G. 04.05.2024 19:22
bash --version не имеет оснований для включения, а также $SHELL (который сообщает вам, какая оболочка настроена по умолчанию для вашей учетной записи пользователя, но не имеет никакого отношения к тому, какая из них активно работает). $BASH_VERSION — единственный достоверный способ (кроме эквивалента массива) узнать, какая версия bash запущена в данный момент; bash --version просто сообщает вам, какая версия стоит первой в PATH, что является отдельной и несвязанной вещью.
Charles Duffy 04.05.2024 20:35

В любом случае, хорошим началом может быть попытка создать воспроизводитель в онлайн-песочнице. Если вы можете реализовать ту же проблему на ideone.com, это означает, что вы достаточно изолировали необходимые элементы, и нам не нужно догадываться о вещах на вашей машине (которых вы, возможно, лично о себе не знаете).

Charles Duffy 04.05.2024 20:36

Однако вы можете также установить PS4=':$BASH_SOURCE:$LINENO+'; set -x перед командой source и проверить, соответствует ли имя файла в выводе xtrace имени файла, который вы выгрузили.

Charles Duffy 04.05.2024 20:40

Что касается вопроса о том, какой экземпляр bash используется, отмечу, что type -a bash и which -a bash указывают, что найден только один экземпляр /bin/bash.

Curtis G. 04.05.2024 20:55

@CharlesDuffy, сценарий выдает ожидаемый результат, используя bash на ideone.com. Этот вывод указывает GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu). Я не вижу никакого способа контролировать используемую там версию bash.

Curtis G. 04.05.2024 21:02

Я должен был предложить repl.it; поскольку для этого можно использовать любой пакет, доступный в Nix, там можно выбрать конкретную версию bash (включая запрос на создание совершенно произвольных сборок из исходного кода).

Charles Duffy 04.05.2024 21:12
Стоит ли изучать 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
15
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

При отсутствии ошибки bash похоже, что что-то заставляет игнорировать команды then или fi. Возможно, существует мошеннический псевдоним, который превосходит встроенную оболочку? Что вы получите, просто

alias

увидеть все псевдонимы?

Да! Это проблема. alias fi='finger -i'. Как только я устраню этот псевдоним, сценарий будет работать как положено.

Curtis G. 07.05.2024 02:16

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