Почему оболочка script дает синтаксические ошибки, когда один и тот же код работает в другом месте?

У меня есть простая оболочка script, которую я скопировал из рабочего script. Он работает, если я скопирую его в терминал:

if true
then
  true
fi 

Однако, когда я запускаю script с bash myscript, я получаю различные синтаксические ошибки, как если бы некоторые из ключевых слов отсутствовали.

  • myscript: line 4: syntax error near unexpected token `fi', как будто then не существует.
  • myscript: line 6: syntax error: unexpected end of file, как будто fi не существует.
  • myscript: line 4: syntax error near unexpected token `$'\r'.. что?

Почему это происходит в данном конкретном script, но не в моей командной строке или в script I, скопированном из?

Ответ 1

TL; DR: ваш script имеет окончание строк CRLF в стиле Windows, ака \r\n.

Преобразовать в стиль Unix \n, удалив возврат каретки.


Как проверить, вернулась ли каретка script?

Они обнаруживаются как ^M в выводе cat -v yourscript:

$ cat -v myscript
if true^M
then^M
  true^M
...

Как удалить их?

Установите редактор, чтобы сохранить файл с окончанием строки Unix, ака "терминаторы строк" ​​или "концевые символы", и сохраните его.

Вы также можете удалить их из командной строки с помощью dos2unix yourscript или cat yourscript | tr -d '\r' > fixedscript.

Почему возврат каретки вызывает синтаксические ошибки?

Символ возврата каретки - это еще один символ до bash. then не совпадает с then\r, поэтому bash не распознает его как ключевое слово и принимает на себя команду. Затем он продолжает искать then и терпит неудачу

Если после then существует конечное пространство, вы получите аналогичную проблему для fi.