Błąd składni Bash: nieoczekiwany koniec pliku


99

Wybacz mi, że to bardzo prosty skrypt w Bash. Oto kod:

#!/bin/bash
# june 2011

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

po uruchomieniu sh file.sh:

błąd składni: nieoczekiwany koniec pliku

Odpowiedzi:


137

Myślę, że file.sh jest z terminatorami linii CRLF.

biegać

dos2unix file.sh

wtedy problem zostanie rozwiązany.

Możesz zainstalować dos2unix w systemie Ubuntu za pomocą tego:

sudo apt-get install dos2unix

Jaki jest powód tego problemu? Zwykle pracuję na systemie Windows, ale muszę przesyłać skrypty do systemów uniksowych.
CMCDragonkai

Nowa linia w systemie Windows to „\ r \ n”, podczas gdy w systemie Linux to „\ n”.
raki

8
@KeesdeKooter Nie powiedziałbym, że tylko dlatego, że coś Ci nie działa, powinieneś to zlekceważyć, najwyraźniej zadziałało przy 28 głosach za. Samo to nie zadziałało dla mnie. Dlatego SO zezwoliło na wiele odpowiedzi na pytanie, ponieważ może istnieć wiele rozwiązań problemu.
Jeff Wilbert,

2
Korzystanie z edytora notepad ++ Edycja> Konwersja EOL> Stary format Mac rozwiązał to za mnie.
raktale

Jeśli możesz edytować swój plik bash za pomocą Notepad ++. Idź do Edycja-> Konwersja EOL-> Macintosh (CR). Zmień go na Macintosh (CR), nawet jeśli używasz systemu operacyjnego Windows.
Juniar

127

Kolejna rzecz do sprawdzenia (właśnie wydarzyła mi się):

  • treści funkcji jednowierszowych kończy się średnikiem

To znaczy ten niewinnie wyglądający fragment spowoduje ten sam błąd:

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

Aby uszczęśliwić głupiego parsera:

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

3
+1 Dotyczy również fragmentów kodu z nawiasami takimi jak: [["$ #" == 1]] && [["$ arg" == [1,2,3,4]]] && printf "% s \ n „bla” || {printf "% s \ n" "blahblah"; stosowanie; } ............ Zwróć uwagę na średnik w nawiasach falistych, zaraz po wywołaniu wcześniej zdefiniowanej funkcji „użycie”. Zapominając o tym, otrzymasz ten sam błąd składni: nieoczekiwany eof.
Cbhihe

Udało wam się. Właściwie prostą rzeczą jest ;to, że oczekiwane jest zakończenie instrukcji Every ;tak, że na końcu np .: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fispowoduje to błąd, natomiast if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;nie ... zwróć uwagę na małe średniki na końcu, czyli: after .bashi fi.
Emmanuel Mahuni

1
Miałem to w skrypcie udostępnionym mi przez zshużytkownika. Ten pierwszy działa, zshale nie działa w shnor bash. Chciałbym mieć 4 osoby, abym mógł oddać te 4 głosy za
Davos,

42

właśnie otrzymałem ten komunikat o błędzie, używając niewłaściwej składni w ifklauzuli

  • else if (błąd składni: nieoczekiwany koniec pliku)
  • elif (poprawna składnia)

debugowałem go, komentując fragmenty, dopóki nie zadziałało


Dziękuję bardzo ... niech ktoś da temu facetowi medal
Happiehappie,

17

niezamknięta klauzula if => fi również to podniesie

wskazówka: użyj pułapki do debugowania, jeśli twój skrypt jest ogromny ...

na przykład

set -x
trap read debug

1
Dokładnie zapomniałem o „fi”! Dzięki :) Gdybyś mógł, dla dobra wszystkich, opowiedz trochę o swojej końcówce używania pułapki.
Carles Alcolea,

3
przepraszam za opóźnienie, przyjacielu. Polecenie „pułapka” to sposób na debugowanie skryptów przez zasadnicze przerywanie po każdym wierszu. Pełniejsza dyskusja jest tutaj: stackoverflow.com/questions/9080431/ ...
theRiley

1
To było przydatne, wielkie dzięki. Zwróć uwagę, że unexpected end of filebłąd wystąpi natychmiast po fitrafieniu.
Stephane B.

8

Otrzymałem tę odpowiedź z tego podobnego problemu na StackOverflow

Otwórz plik w Vimie i spróbuj

:set fileformat=unix

Przekonwertuj zakończenia linii eh na końcówki uniksowe i zobacz, czy to rozwiązuje problem. Jeśli edytujesz w Vimie, wpisz polecenie: set fileformat = unix i zapisz plik. Kilka innych edytorów ma możliwość konwertowania końcówek linii, takich jak Notepad ++ lub Atom

Dzięki @lemongrassnginger


To tylko alternatywne sposoby postępowania dos2unixzgodnie z zaleceniami zaakceptowanej odpowiedzi.
ulidtko

7

na cygwin potrzebowałem: -

 export SHELLOPTS
 set -o igncr

w .bash_profile. W ten sposób nie musiałem uruchamiać unix2dos


6

Więc znalazłem ten post, a odpowiedzi mi nie pomogły, ale udało mi się dowiedzieć, dlaczego spowodował błąd. mam

cat > temp.txt < EOF
some content
EOF

Problem polegał na tym, że skopiowałem powyższy kod, aby był w funkcji i nieumyślnie wstawiłem kod tabulatorem. Należy się upewnić, że ostatni EOF nie jest umieszczony na karcie.


1
To był dokładnie mój przypadek. Zrobiłem EOFwcięcie o cztery spacje i przez to bash go nie przeanalizował. Usunięcie spacji rozwiązało problem.
aexl

5

Miałem problem, gdy napisałem instrukcję „if-fi” w jednej linii:

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

Napisz multiline rozwiązał mój problem:

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

3

Działo się to u mnie, gdy próbowałem wywołać funkcję za pomocą parenów, np

run() {
  echo hello
}

run()

Powinien być:

run() {
  echo hello
}

run

2

DLA WINDOWSA:

W moim przypadku pracowałem na systemie operacyjnym Windows i wystąpił ten sam błąd podczas uruchamiania autoconf.

  • Po prostu otwieram plik configure.ac za pomocą mojego IDE NOTEPAD ++ .
  • Następnie przekonwertowałem plik z konwersją EOL na Windows (CR LF) w następujący sposób:

    EDYCJA -> KONWERSJA EOL -> WINDOWS (CR LF)


1

Udało mi się wyciąć i wkleić twój kod do pliku i działał poprawnie. Jeśli wykonasz to w ten sposób, powinno działać:

Twój „file.sh”:

#!/bin/bash
# june 2011

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

Komenda:

$ ./file.sh arg1 arg2 arg3

Pamiętaj, że plik „file.sh” musi być wykonywalny:

$ chmod +x file.sh

Możesz otrzymać ten błąd b / c tego, jak robisz dane wejściowe (z rurką, marchewką itp.). Możesz również spróbować podzielić warunek na dwie części:

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

Lub, ponieważ używasz bash, możesz użyć wbudowanej składni:

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

I na koniec, możesz oczywiście po prostu sprawdzić, czy podano 3 argumenty (czyste, zachowuje zgodność powłoki POSIX):

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

nadal mam ten sam błąd. nie jestem do końca pewien, gdzie kod idzie źle
markcruz

dziwne, wyciąłem i wkleiłem twój kod i zadziałał zgodnie z oczekiwaniami. czy było więcej błędów? przez długi czas bash wyświetli numer linii. także jaki system używasz? (Linux, MacOS, BSD, dystrybucja itp.)
aaronstacy,

1

Brak nawiasu zamykającego w definicji funkcji spowoduje ten błąd, tak jak właśnie odkryłem.

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

Która oczywiście powinna wyglądać tak ...

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

0

Właśnie wyciąłem i wkleiłem twój przykład do pliku; działało dobrze pod bash. Nie widzę z tym żadnych problemów.

Na wszelki wypadek możesz chcieć upewnić się, że kończy się znakiem nowej linii, chociaż bash nie powinien się tym przejmować. (U mnie działa zarówno z ostatnią nową linią, jak i bez niej.)

Czasami zobaczysz dziwne błędy, jeśli przypadkowo osadziłeś znak kontrolny w pliku. Ponieważ jest to krótki skrypt, spróbuj utworzyć nowy skrypt, wklejając go z pytania tutaj w StackOverflow lub po prostu wpisując go ponownie.

Jakiej wersji basha używasz? ( bash --version)

Powodzenia!


0

Upewnij się, że nazwa katalogu, w którym znajduje się plik .sh, nie zawiera spacji. np .: Powiedz, że jeśli znajduje się on w folderze o nazwie „Nowy folder”, z pewnością natrafisz na zacytowany błąd. Zamiast tego nadaj mu nazwę „Nowy_folder”. Mam nadzieję, że to pomoże.


0

Najwyraźniej niektóre wersje powłoki mogą również emitować ten komunikat, gdy w ostatnim wierszu twojego skryptu brakuje znaku nowej linii.


0

W Ubuntu:

$ gedit ~/.profile

Wtedy, File -> Save asi ustawić end linenaUnix/Linux



0

Dla osób używających MacOS:

Jeśli otrzymałeś plik w formacie Windows i chciałeś uruchomić na MacOS i widzisz ten błąd, uruchom te polecenia.

brew install dos2unix
sh <file.sh>

0

W moim przypadku jest to zbędne \w następującym:

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
}

Istnieje NIE\ na koniecDATA.PATH_PREFIX ./afs/kinetics400

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.