Lỗi cú pháp bash: kết thúc tệp không mong muốn


98

Thứ lỗi cho tôi vì đây là một script rất đơn giản trong Bash. Đây là mã:

#!/bin/bash
# june 2011

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

sau khi chạy sh file.sh:

lỗi cú pháp: kết thúc tệp không mong muốn

Câu trả lời:


137

Tôi nghĩ rằng file.sh là với các trình kết thúc dòng CRLF.

chạy

dos2unix file.sh

thì vấn đề sẽ được khắc phục.

Bạn có thể cài đặt dos2unix trong ubuntu với cái này:

sudo apt-get install dos2unix

Lý do đằng sau vấn đề này là gì? Tôi thường làm việc trên Windows nhưng cần chuyển tập lệnh sang hệ thống unix.
CMCDragonkai

Dòng mới trong windows là "\ r \ n", trong khi trong linux là "\ n".
clyfish

8
@KeesdeKooter Tôi sẽ không nói chỉ vì điều gì đó không phù hợp với bạn mà bạn nên từ chối nó, rõ ràng nó đã hoạt động cho 28 lượt ủng hộ. Một đơn giản nó không hoạt động đối với tôi đủ. Đó là lý do tại sao SO cho phép nhiều câu trả lời cho một câu hỏi vì có thể có nhiều giải pháp cho một vấn đề.
Jeff Wilbert,

2
Sử dụng trình chỉnh sửa notepad ++ Edit> EOL Conversion> Old Mac Format đã giải quyết được vấn đề đó cho tôi.
raktale

Nếu bạn có thể Chỉnh sửa tệp bash của mình bằng Notepad ++. Đi tới Chỉnh sửa-> Chuyển đổi EOL-> Macintosh (CR). Thay đổi nó thành Macintosh (CR) ngay cả khi bạn đang sử dụng hệ điều hành Windows.
Juniar

126

Một điều khác cần kiểm tra (vừa xảy ra với tôi):

  • chấm dứt nội dung của các hàm một dòng bằng dấu chấm phẩy

Tức là đoạn mã trông có vẻ ngây thơ này sẽ gây ra cùng một lỗi:

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

Để làm cho người phân tích cú pháp ngu ngốc hạnh phúc:

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

3
+1 Cũng áp dụng cho các đoạn mã có dấu ngoặc đơn như vậy: [["$ #" == 1]] && [["$ arg" == [1,2,3,4]]] && printf "% s \ n "" bla bla "|| {printf "% s \ n" "blahblah"; sử dụng; } ............ Lưu ý rằng dấu chấm phẩy bên trong dấu ngoặc vuông, ngay sau khi gọi một số hàm được xác định trước đó là 'cách sử dụng'. Việc quên điều đó sẽ khiến bạn gặp phải lỗi cú pháp tương tự: eof không mong muốn.
Cbhihe

bạn đã đóng đinh nó. Trên thực tế, điều đơn giản là ;câu lệnh Every đang được mong đợi kết thúc bằng ;cách đặt ở cuối ví dụ: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fisẽ tạo ra lỗi đó, trong khi if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;sẽ không ... chú ý đến dấu chấm phẩy nhỏ ở cuối, tức là: sau .bashfi.
Emmanuel Mahuni

1
Tôi đã có điều này trong một tập lệnh được chia sẻ với tôi từ một zshngười dùng. Trước đây không làm việc trong zshnhưng không trong shvà cũng không bash. Ước gì tôi có 4 người để tôi có thể đưa ra 4 phiếu ủng hộ này
Davos

40

tôi cũng vừa nhận được thông báo lỗi này do sử dụng sai cú pháp trong một ifmệnh đề

  • else if (lỗi cú pháp: kết thúc tệp không mong muốn)
  • elif (đúng cú pháp)

tôi đã gỡ lỗi nó bằng cách bình luận từng bit cho đến khi nó hoạt động


Cảm ơn bạn rất nhiều .. ai đó làm ơn hãy trao huy chương cho anh chàng này
Happiehappie

16

mệnh đề if => fi không đóng cũng sẽ nêu lên điều này

mẹo: sử dụng bẫy để gỡ lỗi, nếu tập lệnh của bạn lớn ...

ví dụ

set -x
trap read debug

1
Tôi chính xác là quên "fi"! Cảm ơn :) Nếu bạn có thể, vì lợi ích của mọi người, hãy giải thích một chút về mẹo sử dụng bẫy của bạn.
Carles Alcolea

3
xin lỗi vì sự chậm trễ, bạn của tôi. lệnh 'trap' là một cách để gỡ lỗi các tập lệnh của bạn bằng cách ngắt sau mỗi dòng. một cuộc thảo luận đầy đủ hơn là ở đây: stackoverflow.com/questions/9080431/...
theRiley

1
Đó là hữu ích, cảm ơn rất nhiều. Lưu ý rằng unexpected end of filelỗi sẽ xảy ra ngay sau khi fiđược đánh.
Stephane B.

8

Tôi đã nhận được câu trả lời từ vấn đề tương tự này trên StackOverflow

Mở tệp bằng Vim và thử

:set fileformat=unix

Chuyển đổi phần cuối dòng eh thành phần cuối unix và xem liệu điều đó có giải quyết được vấn đề hay không. Nếu chỉnh sửa trong Vim, nhập lệnh: set fileformat = unix và lưu tệp. Một số trình chỉnh sửa khác có khả năng chuyển đổi kết thúc dòng, chẳng hạn như Notepad ++ hoặc Atom

Xin cảm ơn @lem Citatinger


Đây chỉ là những cách thay thế để làm dos2unixnhư câu trả lời được chấp nhận khuyên.
ulidtko

7

trên cygwin tôi cần: -

 export SHELLOPTS
 set -o igncr

trong .bash_profile. Bằng cách này, tôi không cần chạy unix2dos


6

Vì vậy, tôi đã tìm thấy bài đăng này và các câu trả lời không giúp được tôi nhưng tôi đã có thể tìm ra lý do tại sao nó gây ra lỗi cho tôi. Tôi đã có một

cat > temp.txt < EOF
some content
EOF

Vấn đề là tôi đã sao chép đoạn mã trên vào một hàm và vô tình gắn thẻ mã. Cần đảm bảo rằng EOF cuối cùng không được gắn thẻ.


1
Đây chính xác là trường hợp của tôi. Tôi đã EOFthụt vào trong bốn khoảng trắng và bash không phân tích cú pháp vì điều đó. Xóa khoảng trắng đã khắc phục sự cố.
aexl

5

Tôi đã gặp sự cố khi viết câu lệnh "if - fi" trong một dòng:

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

Viết nhiều dòng đã giải quyết được vấn đề của tôi:

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

3

Điều này đã xảy ra với tôi khi tôi cố gắng gọi một hàm bằng cách sử dụng parens, ví dụ:

run() {
  echo hello
}

run()

nên là:

run() {
  echo hello
}

run

2

CHO CỬA SỔ:

Trong trường hợp của tôi, tôi đang làm việc trên Hệ điều hành Windows và tôi gặp lỗi tương tự khi chạy autoconf.

  • Tôi chỉ cần mở tệp config.ac bằng IDE NOTEPAD ++ của mình .
  • Sau đó, tôi đã chuyển đổi tệp có chuyển đổi EOL thành Windows (CR LF) như sau:

    EDIT -> EOL CONVERSION -> WINDOWS (CR LF)


1

Tôi đã có thể cắt và dán mã của bạn vào một tệp và nó chạy chính xác. Nếu bạn thực thi nó như thế này, nó sẽ hoạt động:

"File.sh" của bạn:

#!/bin/bash
# june 2011

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

Lệnh:

$ ./file.sh arg1 arg2 arg3

Lưu ý rằng "file.sh" phải có thể thực thi được:

$ chmod +x file.sh

Bạn có thể nhận được lỗi đó b / c về cách bạn đang nhập liệu (w / a pipe, củ cà rốt, v.v.). Bạn cũng có thể thử tách điều kiện thành hai:

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

Hoặc, vì bạn đang sử dụng bash, bạn có thể sử dụng cú pháp tích hợp:

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

Và, cuối cùng, tất nhiên bạn có thể chỉ cần kiểm tra xem 3 đối số đã được đưa ra chưa (sạch, duy trì khả năng tương thích của trình bao POSIX):

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

tôi vẫn gặp lỗi tương tự. im không chắc chắn chính xác nơi mã đi sai
markcruz

kỳ lạ, tôi đã cắt và dán mã của bạn và nó hoạt động như mong đợi. có bất kỳ đầu ra lỗi nữa không rất nhiều thời gian bash sẽ liệt kê một số dòng. ngoài ra, bạn đang chạy hệ thống nào? (Linux, hệ điều hành MacOS, BSD, distro, vv)
aaronstacy

0

Tôi vừa cắt và dán ví dụ của bạn vào một tệp; nó chạy tốt dưới bash. Tôi không thấy có vấn đề gì với nó.

Để có biện pháp tốt, bạn có thể muốn đảm bảo nó kết thúc bằng một dòng mới, mặc dù bash không nên quan tâm. (Nó chạy cho tôi cả có và không có dòng mới cuối cùng.)

Đôi khi bạn sẽ thấy các lỗi lạ nếu bạn đã vô tình nhúng một ký tự điều khiển vào tệp. Vì đó là một tập lệnh ngắn, hãy thử tạo một tập lệnh mới bằng cách dán nó từ câu hỏi của bạn tại đây trên StackOverflow hoặc chỉ cần nhập lại.

Bạn đang sử dụng phiên bản bash nào? ( bash --version)

Chúc may mắn!


0

Đảm bảo rằng tên của thư mục chứa tệp .sh không có ký tự khoảng trắng. Ví dụ: Giả sử nếu nó nằm trong một thư mục có tên là 'Thư mục Mới', thì bạn chắc chắn sẽ gặp phải lỗi mà bạn đã trích dẫn. Thay vào đó, chỉ cần đặt tên nó là 'New_Folder'. Tôi hi vọng cái này giúp được.


0

Rõ ràng, một số phiên bản của shell cũng có thể phát ra thông báo này khi dòng cuối cùng của tập lệnh của bạn thiếu một dòng mới.


0

Trong Ubuntu:

$ gedit ~/.profile

Sau đó, File -> Save asvà đặt end linethànhUnix/Linux



0

Đối với những người sử dụng MacOS:

Nếu bạn nhận được tệp có định dạng Windows và muốn chạy trên MacOS và gặp lỗi này, hãy chạy các lệnh này.

brew install dos2unix
sh <file.sh>

0

Thiếu dấu ngoặc nhọn đóng trên định nghĩa hàm sẽ gây ra lỗi này như tôi vừa phát hiện.

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

Tất nhiên là phải như thế này ...

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

0

Trong trường hợp của tôi, có thừa \trong những thứ tương tự như sau:

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
}

KHÔNG một \vào cuối nămDATA.PATH_PREFIX ./afs/kinetics400

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.