Bash

在 Windows 上編輯的 Bash/Korn shell 腳本拋出錯誤“…^M: not found”

  • April 14, 2019

我使用 Notepad++ 在 Windows 中編寫了一個 Bash 腳本。

cxStopAllServicesOnSERVER.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

現在上傳並設置所需的文件權限後,我嘗試按如下方式執行它:

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.

問題: 當我將程式碼更改為 korn shell 時,我遇到了同樣的問題。似乎在行尾添加了不正確的字元。

注意: 我找到了解決方案並發布了與答案相同的內容。隨時更新或改進它,以幫助可能面臨相同問題的其他初學者。謝謝!

在窺探各種論壇和一些 Stack-overflow 文章後,我發現了這個問題。

這是一個解釋,以更好地理解和“查看”錯誤的根本原因。

首先,如果您在 Windows 上編寫程式碼,最好用 Notepad++ 武裝自己。在我看來,它基本上是文本編輯器的瑞士軍刀。

現在查看 EOL(行尾)字元和其他控制符號,請執行以下操作:

1.在記事本++中打開文件。

從菜單欄中選擇視圖 > 顯示符號 > 顯示所有字元

您現在應該看到如下符號: Notepad++ 截圖:在 Windows 上編輯 UNIX 腳本

啊哈!Windows/MS-DOS 使用 CR+LF 來表示行尾。現在 UNIX 使用 LF 字元來表示行終止符(EOL 字元)。

2.1.讓我們將 Windows EOL 轉換為 UNIX EOL:

選擇編輯 > EOL 轉換 > UNIX 格式

您應該看到如下內容:

Notepad++ 截圖:EOL 轉換為 UNIX 格式 這就解釋了為什麼我們看到 ‘\r’ 字元被附加在行尾。這是因為 UNIX 將 ‘\n’ 或 LF(換行符)辨識為行終止符/EOL 字元,但忽略了 ‘\r’ 或 ^M(輸入符)字元。

我們還可以通過以下方式測試 EOL 問題

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.如果您想在 UNIX 上將文件從 Windows 轉換為 UNIX EOL 格式,則有兩種方法可以解決此問題:

$ dos2unix myScript.sh

或者

使用**@Chris Down**提供的解決方案如下:

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

參考:

  1. 有關線路終止r 和 n 之間的差異的更多資訊,請參閱這些連結。

引用自:https://unix.stackexchange.com/questions/56024