Tập lệnh shell Bash / Korn được chỉnh sửa trên Windows sẽ xuất hiện lỗi '' ^ ^: không tìm thấy '


8

Tôi đã viết một đoạn script Bash trong Windows bằng Notepad ++.

cxStop ALLServiceOnSERVER.sh

#!/usr/bin/bash
cd "/some/path"
echo "Hi. Logs can be found at "`pwd`"/cxStartStopLogger.log"
echo "["`date`"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"
exit

Bây giờ sau khi tải nó lên và thiết lập các quyền tập tin cần thiết, tôi đã thử thực hiện nó như sau:

bash-3.00$ cat cxStopAllServicesOnSERVER.sh #Let's have a look at the code.
#!/usr/bin/bash
cd "/some/path/"
echo "Hi. Logs can be found at "`pwd`"/cxStartStopLogger.log"
echo "["`date`"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"

bash-3.00$ # Code and hashbang 'looks' correct, 
bash-3.00$ # if there is any issue with the format (EOL characters and such) 
bash-3.00$ # we cannot see it using cat.
bash-3.00$ 
bash-3.00$ sh cxStopAllServicesOnSERVER.sh
cxStopAllServicesOnSERVER.sh[2]: /some/path^M:  not found
Hi. Logs can be found at /some/path/cxStartStopLogger.log
bash-3.00$ # Note that ^M appears at the end of the line.

bash-3.00$ bash -x cxStopAllServicesOnSERVER.sh
+ cd $'/some/path\r'
: No such file or directory1.sh: line 2: cd: /some/path
++ pwd
' echo 'Hi. Logs can be found at /some/path/cxStartStopLogger.log
Hi. Logs can be found at /some/path/cxStartStopLogger.log
++ date
+ echo '[Sun' Nov 18 00:28:17 EST '2012]*** STOPPING ALL SERVICES ON SERVER ***'
bash-3.00$ # Note that '\r' return character appears at the end of the line.

Vấn đề: Khi tôi thay đổi mã thành korn shell, tôi gặp phải vấn đề tương tự. Xuất hiện rằng một ký tự không chính xác sẽ được thêm vào cuối dòng.

LƯU Ý: Tôi tìm thấy giải pháp và đã đăng giống như một câu trả lời. Hãy cập nhật hoặc cải thiện nó để giúp những người mới bắt đầu có thể gặp phải vấn đề tương tự. Cảm ơn!

Câu trả lời:


15

Sau khi rình mò các diễn đàn khác nhau và một số bài đăng Stack-overflow tôi đã tìm thấy vấn đề.

Dưới đây là một lời giải thích để hiểu rõ hơn và 'xem' nguyên nhân gốc của các lỗi.

Trước hết, nếu bạn đang viết mã trên Windows, tốt hơn hãy tự mình sử dụng Notepad ++. Về cơ bản, đó là con dao biên tập văn bản của quân đội Thụy Sĩ.

Bây giờ để xem các ký tự EOL (cuối dòng) và các ký hiệu điều khiển khác, hãy làm như sau:

1.Mở tệp trong Notepad ++.

Chọn Xem> Hiển thị Biểu tượng> Hiển thị tất cả các ký tự từ thanh Menu

Bây giờ bạn sẽ thấy các biểu tượng như sau: Ảnh chụp màn hình của Notepad ++: Chỉnh sửa tập lệnh UNIX trên Windows

Aha! Windows / MS-DOS sử dụng CR + LF để biểu thị các dòng cuối. Bây giờ UNIX sử dụng ký tự LF để biểu thị chấm dứt dòng (ký tự EOL).

2.1.Để chuyển đổi Windows EOL thành UNIX EOL:

Chọn EDIT> Chuyển đổi EOL> Định dạng UNIX

Bạn sẽ thấy một cái gì đó như thế này:

Ảnh chụp màn hình của Notepad ++: Chuyển đổi EOL sang định dạng UNIX Điều này giải thích lý do tại sao chúng tôi thấy ký tự '\ r' được thêm vào cuối dòng. Điều này là do UNIX nhận ra '\ n' hoặc LF (linefeed) là ký tự chấm dứt dòng / EOL mà bỏ qua ký tự '\ r' hoặc ^ M (trả về vận chuyển).

Chúng tôi cũng có thể kiểm tra sự cố EOL bằng cách

bash-3.00$ head myScript.sh | cat -vet | head -1
#usr/bin/bash^M$
bash-3.00$ #We see that ^M, that is \r is found at the end of each line. 

2.2. Nếu bạn muốn chuyển đổi tệp từ định dạng Windows sang UNIX EOL trên UNIX thì có hai cách khắc phục điều này:

$ dos2unix myScript.sh

hoặc là

Sử dụng giải pháp được cung cấp bởi @Chris Down như dưới đây:

$ sed -i 's/\r$//' myScript.sh

Người giới thiệu:

  1. Để biết thêm thông tin về chấm dứt dòngnhững gì là khác biệt giữa r-và-n hãy tham khảo các liên kết này.

1
Câu trả lời tuyệt vời! Tôi nghĩ rằng đối với những điều nhỏ gắn bó pico, trình soạn thảo dòng lệnh, sẽ là giải pháp.
João Pimentel Ferreira

4

Tập lệnh của bạn chứa các kết thúc dòng CRLF, trong khi Unix sử dụng các kết thúc dòng LF. Sau đây sẽ loại bỏ chúng, nếu bạn có GNU sed:

sed -i 's/\r$//' cxStopAllServicesOnSERVER.sh

Nếu bạn không có GNU sed , hãy ghi vào một tệp tạm thời, rồi di chuyển nó lên trên cùng của tệp cũ.

Bên cạnh đó, nếu bạn gọi một tập lệnh bằng cách sử dụng sh, bạn sẽ ghi đè lên shebang. Đó có lẽ không phải là những gì bạn muốn.


1
Công dos2unixcụ này cũng đáng để đề xuất.
jordanm

@jordanm Yup. Tôi đã trình bày nó trong bài viết của tôi dưới đây.
Kent Pawar

không có shebang được xác định. !/phải được chèn vào dòng đầu tiên để có một.
phép lạ173

@ miracle173 Tôi cho rằng đó là một lỗi đánh máy hơn là cố ý.
Chris Xuống
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.