Когда я использую следующий простой скрипт в оболочке 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
Можете ли вы опубликовать результат команды od -a your-script
?
Я могу воспроизвести это, если строка fi
заканчивается возвратом каретки. Исправьте скрипт с помощью dos2unix
Я почти уверен, что в сценарии нет случайных символов CR. 1) Я написал сценарий в той же системе MacOS. 2) grep ^M bash-if-trouble.sh
не производит результата. 3) Мой редактор указывает окончания строк LF.
Что печатает /bin/bash --version
?
@CurtisG — ваши комментарии по поводу вывода od -a bash-if-trouble.sh
лучше всего будут представлены в вопросе — вы сможете отформатировать информацию для удобства чтения.
Можешь попробовать source ./bash-if-trouble.sh
?
Пожалуйста, добавьте echo "$BASH_VERSION"
в свой скрипт, а затем добавьте этот вывод в свой вопрос, чтобы мы могли видеть, какую версию bash вы используете при исходном коде сценария. Шебанг вверху, #!/bin/bash
будет игнорироваться при его получении, кстати, код будет запускаться в любой оболочке, которую вы запускаете при исходном файле. Кроме того, echo "$SHELL"
просто сообщает нам оболочку по умолчанию, но не сообщает, какая оболочка запущена в данный момент.
Спасибо Филиппу, Джону Боллинджеру, Джонатану Леффлеру и Эду Мортону за предложения. Я соответствующим образом обновил тело вопроса.
bash --version
не имеет оснований для включения, а также $SHELL
(который сообщает вам, какая оболочка настроена по умолчанию для вашей учетной записи пользователя, но не имеет никакого отношения к тому, какая из них активно работает). $BASH_VERSION
— единственный достоверный способ (кроме эквивалента массива) узнать, какая версия bash запущена в данный момент; bash --version
просто сообщает вам, какая версия стоит первой в PATH, что является отдельной и несвязанной вещью.
В любом случае, хорошим началом может быть попытка создать воспроизводитель в онлайн-песочнице. Если вы можете реализовать ту же проблему на ideone.com, это означает, что вы достаточно изолировали необходимые элементы, и нам не нужно догадываться о вещах на вашей машине (которых вы, возможно, лично о себе не знаете).
Однако вы можете также установить PS4=':$BASH_SOURCE:$LINENO+'; set -x
перед командой source
и проверить, соответствует ли имя файла в выводе xtrace имени файла, который вы выгрузили.
Что касается вопроса о том, какой экземпляр bash
используется, отмечу, что type -a bash
и which -a bash
указывают, что найден только один экземпляр /bin/bash
.
@CharlesDuffy, сценарий выдает ожидаемый результат, используя bash на ideone.com. Этот вывод указывает GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)
. Я не вижу никакого способа контролировать используемую там версию bash.
Я должен был предложить repl.it; поскольку для этого можно использовать любой пакет, доступный в Nix, там можно выбрать конкретную версию bash (включая запрос на создание совершенно произвольных сборок из исходного кода).
При отсутствии ошибки bash
похоже, что что-то заставляет игнорировать команды then
или fi
. Возможно, существует мошеннический псевдоним, который превосходит встроенную оболочку? Что вы получите, просто
alias
увидеть все псевдонимы?
Да! Это проблема. alias fi='finger -i'
. Как только я устраню этот псевдоним, сценарий будет работать как положено.
У меня работает в crufy bash 3.2, поставляемом с MacOS, в bash 5.2 и даже в zsh.