Помилка синтаксису Bash: несподіваний кінець файлу


98

Вибачте за це, це дуже простий сценарій на Bash. Ось код:

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

після запуску sh file.sh:

синтаксична помилка: несподіваний кінець файлу

Відповіді:


137

Я думаю, що file.sh є з термінаторами рядків CRLF.

бігати

dos2unix file.sh

тоді проблема буде виправлена.

Ви можете встановити dos2unix в ubuntu за допомогою цього:

sudo apt-get install dos2unix

У чому причина цієї проблеми? Я зазвичай працюю в Windows, але мені потрібно перенести сценарії в системи Unix.
CMCDragonkai,

Новий рядок у Windows - "\ r \ n", тоді як у Linux - "\ n".
clyfish

8
@KeesdeKooter Я б не сказав лише тому, що у вас щось не вийшло, що ви повинні проголосувати за це, очевидно, це спрацювало для 28-ти за. Досить простого, що мені не вдалося. Ось чому SO дозволила отримати декілька відповідей на запитання, оскільки проблема може мати кілька варіантів вирішення.
Jeff Wilbert

2
За допомогою редактора notepad ++ Редагувати> Перетворення EOL> Старий формат Mac вирішив це для мене.
raktale

Якщо ви можете редагувати ваш файл bash за допомогою Notepad ++. Перейдіть до Edit-> EOL Conversion-> Macintosh (CR). Змініть його на Macintosh (CR), навіть якщо ви використовуєте ОС Windows.
Juniar

127

Інша річ, яку слід перевірити (що мені трапилося):

  • закінчувати тіла однорядкових функцій крапкою з комою

Тобто цей невинний на вигляд фрагмент спричинить ту саму помилку:

die () { test -n "$@" && echo "$@"; exit 1 }

Щоб зробити німого парсер щасливим:

die () { test -n "$@" && echo "$@"; exit 1; }

3
+1 також застосовується до фрагментів коду з дужками приблизно так: [["$ #" == 1]] && [["$ arg" == [1,2,3,4]]] && printf "% s \ n "" благ "|| {printf "% s \ n" "благбла"; використання; } ............ Зверніть увагу, що крапка з комою всередині криволінійних дужок, відразу після виклику деякої раніше визначеної функції "використання". Забуття, що призведе до тієї самої синтаксичної помилки: несподіваний eof.
Cbhihe

ти впорався. Насправді проста річ - ;передбачається, що закінчення Every закінчується ;таким чином, що наприкінці, наприклад: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fiвидасть цю помилку, тоді як if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;не буде ... помічати маленькі крапки з комою в кінці, тобто: після .bashі fi.
Еммануель Махуні,

1
Це було у мене в сценарії, яким користувач поділився зі мною zsh. Перший працює zshв shні, ні в ні bash. Якби я був 4 людьми, щоб я міг дати ці 4 голоси проти
Давос,

41

Я також щойно отримав це повідомлення про помилку, використовуючи неправильний синтаксис у ifреченні

  • else if (синтаксична помилка: несподіваний кінець файлу)
  • elif (правильний синтаксис)

я налагодив його, коментуючи біти, поки це не спрацювало


Велике спасибі .. хтось, будь ласка, дайте цьому хлопцеві медаль
Happiehappie

16

пропозиція un-closed if => fi також підніме це

порада: використовуйте trap для налагодження, якщо ваш сценарій величезний ...

напр

set -x
trap read debug

1
Я точно забув "fi"! Дякую :) Якщо б ви могли, на благо всіх, трохи докладно розробити свою підказку щодо використання пастки.
Carles Alcolea

3
вибачте за затримку, друже. Команда 'trap' - це спосіб налагодити ваші сценарії, по суті розбиваючись після кожного рядка. більш повне обговорення тут: stackoverflow.com/questions/9080431 / ...
theRiley

1
Це було корисно велике спасибі. Зверніть увагу, що unexpected end of fileпомилка буде виникати, як тільки fiбуде потрапляти.
Стефан Б.

8

Я отримав цю відповідь із подібної проблеми на StackOverflow

Відкрийте файл у Vim і спробуйте

:set fileformat=unix

Перетворіть закінчення рядка eh на закінчення unix і перевірте, чи вирішує це проблему. Якщо редагуєте у Vim, введіть команду: set fileformat = unix та збережіть файл. Декілька інших редакторів мають можливість перетворювати закінчення рядків, наприклад Notepad ++ або Atom

Дякую @lemongrassnginger


Це лише альтернативні способи зробити так, dos2unixяк радить прийнята відповідь.
ulidtko

7

на cygwin мені потрібно було: -

 export SHELLOPTS
 set -o igncr

у .bash_profile. Таким чином, мені не потрібно було запускати unix2dos


6

Тож я знайшов цю публікацію, і відповіді мені не допомогли, але я зміг зрозуміти, чому вона дала мені помилку. я маю

cat > temp.txt < EOF
some content
EOF

Проблема полягала в тому, що я скопіював вищезазначений код, щоб він був функцією, і ненавмисно вклав код у вкладку. Потрібно переконатися, що останній EOF не має вкладки.


1
Це був якраз мій випадок. Я EOFвідступив чотирма пробілами, і Баш не проаналізував його через це. Видалення пробілів вирішило проблему.
aexl

5

У мене виникла проблема, коли я написав в одному рядку заяву "if - fi":

if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi

Написати багаторядковий вирішив мою проблему:

if [ -f ~/.git-completion.bash ]; then 
    . ~/.git-completion.bash
 fi

3

Це відбувалося для мене, коли я намагався викликати функцію за допомогою парен, наприклад

run() {
  echo hello
}

run()

має бути:

run() {
  echo hello
}

run

2

ДЛЯ ВІКН:

У моєму випадку я працював в ОС Windows і отримав ту саму помилку під час запуску autoconf.

  • Я просто відкриваю файл configure.ac зі своїм IDEP NOTEPAD ++ .
  • Потім я перетворив Файл із перетворенням EOL у Windows (CR LF) наступним чином:

    РЕДАГУВАТИ -> КОНВЕРСІЯ EOL -> ВІКНА (CR LF)


1

Я зміг вирізати та вставити ваш код у файл, і він працював правильно. Якщо ви виконуєте його таким чином, він повинен працювати:

Ваш файл "file.sh":

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

Команда:

$ ./file.sh arg1 arg2 arg3

Зверніть увагу, що "file.sh" повинен бути виконуваним:

$ chmod +x file.sh

Можливо, ви отримуєте цю помилку b / c того, як ви робите введення (без труби, моркви тощо). Ви також можете спробувати розділити умову на дві частини:

if [ $# -lt 3 ] || [ $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

Або, оскільки ви використовуєте bash, ви можете використовувати вбудований синтаксис:

if [[ $# -lt 3 || $# -gt 3 ]]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

І, нарешті, ви можете, звичайно, просто перевірити, чи були вказані 3 аргументи (чистий, підтримує сумісність оболонки POSIX):

if [ $# -ne 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

я все ще отримав ту ж помилку. я не точно впевнений, де код йде не так
markcruz

дивно, я вирізав і вставив ваш код, і він працював, як очікувалося. чи було більше помилок? багато часу bash буде перераховувати номер рядка. також, яку систему ви використовуєте? (Linux, MacOS, BSD, дистрибутив тощо)
aaronstacy

0

Я просто вирізав і вставив ваш приклад у файл; це чудово бігло під Баш. Я не бачу з цим жодних проблем.

Для гарного заходу ви можете переконатись, що він закінчується новою лінією, хоча bash не повинен хвилювати. (Він працює для мене як з кінцевим новим рядком, так і без нього.)

Іноді ви побачите дивні помилки, якщо випадково вбудували керуючий символ у файл. Оскільки це короткий сценарій, спробуйте створити новий сценарій, вставивши його зі свого запитання тут, на StackOverflow, або просто повторно набравши його.

Яку версію bash ви використовуєте? ( bash --version)

Удачі!


0

Переконайтесь, що ім’я каталогу, у якому знаходиться файл .sh, не має пробілу. наприклад: Скажімо, якщо вона знаходиться в папці під назвою 'Нова папка', ви обов'язково зіткнетеся з помилкою, яку ви цитували. Натомість просто назвіть його як 'New_Folder'. Я сподіваюся, що це допомагає.


0

Очевидно, деякі версії оболонки також можуть видавати це повідомлення, коли в останньому рядку вашого сценарію відсутній новий рядок.


0

В Ubuntu:

$ gedit ~/.profile

Потім File -> Save asі встановіть end lineнаUnix/Linux



0

Для людей, які використовують MacOS:

Якщо ви отримали файл у форматі Windows і хочете запустити на MacOS і побачили цю помилку, запустіть ці команди.

brew install dos2unix
sh <file.sh>

0

Відсутність фінальної дужки у визначенні функції спричинить цю помилку, як я щойно виявив.

function whoIsAnIidiot() {
    echo "you are for forgetting the closing brace just below this line !"

Що, звичайно, має бути таким ...

function whoIsAnIidiot() {
    echo "not you for sure"
}

0

У моєму випадку є надлишок приблизно \такого:

function foo() {
    python tools/run_net.py \
                           --cfg configs/Kinetics/X3D_8x8_R50.yaml \
                           NUM_GPUS 1 \
                           TRAIN.BATCH_SIZE 8 \
                           SOLVER.BASE_LR 0.0125 \
                           DATA.PATH_TO_DATA_DIR ./afs/kinetics400 \
                           DATA.PATH_PREFIX  ./afs/kinetics400  \  # Error
}

В кінці НЕ є \аDATA.PATH_PREFIX ./afs/kinetics400

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.