it-roy-ru.com

синтаксическая ошибка рядом с неожиданным токеном '- bash

Я написал пример скрипта на моем Mac 

#!/bin/bash
test() {
  echo "Example"
}
test
exit 0

и это прекрасно работает, отображая пример

Когда я запускаю этот скрипт на машине RedHat, он говорит

синтаксическая ошибка рядом с неожиданным токеном

Я проверил, что Bash доступен с помощью

cat /etc/shells

which bash shows /bin/bash 

Кто-нибудь сталкивался с такой же проблемой?

Заранее спасибо !

12
user3155779

Это может быть проблема с кодировкой файла.

Я сталкивался с проблемами кодирования типов файлов при работе с файлами между различными операционными системами и редакторами - в моем случае, особенно между системами Linux и Windows.

Я предлагаю проверить кодировку вашего файла, чтобы убедиться, что он подходит для целевой среды Linux. Я предполагаю, что проблема с кодировкой менее вероятна, если вы используете MAC, чем если бы вы использовали текстовый редактор Windows, однако я думаю, что кодирование файлов все же стоит рассмотреть.

--- РЕДАКТИРОВАТЬ (Добавить реальное решение в соответствии с рекомендациями @Potatoswatter) 

Чтобы продемонстрировать, как проблема может быть связана с кодировкой типов файлов, я скопировал/вставил ваш пример сценария в Блокнот в Windows (у меня нет доступа к Mac), затем скопировал его на машину linux и запустил: 

[email protected]:~/windows> sh ./originalfile             
./originalfile: line 2: syntax error near unexpected token `$'{\r''
'/originalfile: line 2: `test() {

В этом случае Блокнот сохранил файл с возвратом каретки и переводом строки, что привело к ошибке, показанной выше. \r указывает на возврат каретки (системы Linux заканчивают строки только переводами строк \n). 

На Linux-машине вы можете проверить эту теорию, выполнив следующее, чтобы убрать возврат каретки из файла, если они присутствуют:

cat originalfile | tr -d "\r" > newfile

Затем попробуйте запустить новый файл sh ./newfile. Если это работает, проблема заключалась в возврате каретки как скрытых символов. 

Примечание: Это не точная репликация вашей среды (у меня нет доступа к Mac), однако мне кажется вероятным, что проблема в том, что редактор, где-то сохраненная каретка, возвращается в файл. 

--- /Правка 

Чтобы уточнить, операционные системы и редакторы могут иметь различные значения по умолчанию для кодировки файлов. Как правило, приложения и редакторы влияют на используемую кодировку типов файлов, например, я думаю, что для Microsoft Notepad и Notepad ++ по умолчанию используется Windows-1252. Также могут быть различия между строками новой строки (в средах Windows возврат каретки и перевод строки часто используются для завершения строк в файлах, в то время как в Linux и OSX обычно используется только перевод строки). 

Аналогичный вопрос и ответ, который ссылается на кодировку файла, находится здесь: плохой символ появляется при выполнении скрипта bash

25
jdt

Простой способ конвертировать файл example.sh в UNIX, если вы работаете в Windows, это использовать NotePad ++ («Правка»> «Преобразование EOL»> «Формат UNIX/OSX»).

Вы также можете установить EOL по умолчанию в notepad ++ («Настройки»> «Настройки»> «Новый документ/Каталог по умолчанию»> выберите «Unix/OSX» в поле «Формат»).

4
JAR

попробуй что-то вроде

$ Sudo apt-get install dos2unix
$ dos2unix offendingfile
4
Amos Folarin

Спасибо @jdt за ваш ответ.

После этого, и поскольку у меня продолжает возникать проблема с возвратом каретки, я написал этот небольшой сценарий. Запустите только carriage_return, и вам будет предложено «очистить» файл.

https://Gist.github.com/kartonnade/44e9842ed15cf21a3700

alias carriage_return=remove_carriage_return
remove_carriage_return(){

# cygwin throws error like : 
# syntax error near unexpected token `$'{\r''
# due to carriage return
# this function runs the following
# cat originalfile | tr -d "\r" > newfile

read -p "File to clean ? "
file_to_clean=$REPLY
temp_file_to_clean=$file_to_clean'_'

# file to clean => temporary clean file
remove_carriage_return_one='cat '$file_to_clean' | tr -d "\r" > '
remove_carriage_return_one=$remove_carriage_return_one$temp_file_to_clean

# temporary clean file => new clean file
remove_carriage_return_two='cat '$temp_file_to_clean' | tr -d "\r" > '
remove_carriage_return_two=$remove_carriage_return_two$file_to_clean

eval $remove_carriage_return_one
eval $remove_carriage_return_two
# remove temporary clean file 
eval 'rm '$temp_file_to_clean

}

2
kartonnade

Я хочу добавить к ответ выше is как проверить, является ли это проблемой возврата каретки в Unix-подобной среде (я тестировал в MacOS)

1) Использование кошки

cat -e my_file_name

Если вы видите строки, оканчивающиеся на ^M$, тогда да, это проблема возврата каретки.

2) Найти первую строку с символом возврата каретки

grep -r $'\r' Grader.sh | head -1

3) Использование vim

vim my_file_name

Затем в VIM введите

:set ff

Если вы видите fileformat=dos, то это файл из среды dos, который содержит возврат каретки.

После выяснения, вы можете использовать вышеупомянутые методы другими людьми, чтобы исправить ваш файл.

0
traceformula