在 Windows 上執行 Bash Script 時,遇到「$'\r': command not found」錯誤,問題倒不是因為程式語法錯誤,而是跨作業系統開發時會遇到的換行符號差異。只要將 Windows 的 CRLF 換行格式轉換為 Unix/Linux 使用的 LF,就可以解決。
![]() |
| Photo by Christina Morillo on StockSnap |
錯誤狀況
Cygwin 環境下執行 bash 出現錯誤「$'\r': command not found」
$ bash example.sh
example.sh: line 3: $'\r': command not found
: invalid option name set: pipefail
example.sh: line 5: $'\r': command not found
example.sh: line 8: $'\r': command not found
example.sh: line 9: syntax error near unexpected token `$'{\r''
解決方法
1. 下載與安裝 Cygwin 安裝程式
2. 執行 Cygwin,開啟視窗介面,確認是否已經安裝 dos2unix 套件,輸入指令:
$ which dos2unix
3. 如果 dos2unix 不存在,需要安裝 dos2unix 套件。離開 Cygwin 視窗,在 Windows 命令列提示字元執行:
setup-x86_64.exe -q -P dos2unix
參數說明
- setup-x86_64.exe:Cygwin 64 位元安裝程式。
- -q:安靜模式(quiet mode),不顯示一般安裝介面。
- -P dos2unix:指定要安裝的套件名稱為 dos2unix。
也可以透過 Cygwin 視窗介面安裝,請參考連結
4. 執行 Cygwin,開啟視窗介面
5. Cygwin 環境下執行 cd 指令,切換到 bash 檔案所在的資料夾
$ cd c:\path\to\folder
或
$ cd /cygdrive/c/path/to/folder
6. Cygwin 環境下執行 dos2unix 指令,將 bash 檔案的換行符號,從 Windows 的 CRLF 換行 (\r\n) 格式,轉換成 Unix/Linux 的 LF 換行格式 (\n)。
$ dos2unix example.sh
或者一次轉換目前目錄下的多個 bash 檔案
$ dos2unix *.sh
7. 再次執行 bash 檔案,就不會遇到相同錯誤
$ bash example.sh
如果不使用 dos2unix,網路上提供使用 sed 程式轉換換行符號的指令,將指定檔案中的 \r 移除,可自行嘗試
sed -i 's/\r$//' example.sh
探討問題原因
bash 檔案是透過 GIT 從 macOS 同步 (clone 或 pull) 到 Windows Server。雖然 macOS 文字檔案預設換行符號是 \n,但是因為 Windows Server 的 GIT 設定了自動轉換換行符號是 \r\n,而造成錯誤。
1. 檢查 GIT 設定,在 Windows 命令列提示字元執行:
git config --get core.autocrlf
回傳結果 true。
設定 core.autocrlf=true ,Git 在 Windows 工作目錄簽出 (check out) 檔案時會將 LF 轉換成 CRLF;在提交 (commit) 時則會把 CRLF 正規化為 LF。此設定可能會被 .gitattributes 中的換行規則覆蓋。(資料來源:git-scm.com)
2. 使用 .gitattributes 強制規範換行符號
在 GIT 專案的根目錄位置,新增檔案 .gitattributes
*.sh text eol=lf
3. 將 GIT 專案套用新的 .gitattributes 規則
git add .gitattributes
git add --renormalize .
git status # 確認哪些檔案被重新正規化
git commit -m "Normalize line endings for shell scripts"
git push
參數說明
- git add:把變更加入暫存區。
- --renormalize:重新讀取已追蹤檔案 Tracked files,並依目前的 .gitattributes 設定,重新套用換行正規化及其他加入 Git 暫存區前的內容轉換規則 (Git clean filter)。
- .:處理目前目錄及所有子目錄
4. Windows 透過 git 同步正規化設定
git pull
參考資料
- Cygwin - 維基百科,自由的百科全書 https://zh.wikipedia.org/zh-tw/Cygwin 「Cygwin是許多自由軟體的集合,最初由Cygnus Solutions開發,用於各種版本的Microsoft Windows上,執行類UNIX系統。」
- windows - Cygwin Dos2Unix Command not found - Super User https://superuser.com/questions/612435/cygwin-dos2unix-command-not-found
- dos2unix 指令在 Cygwin 裡面找不到。在其他電腦上安裝的 Cygwin 都可以用,所以不知道為什麼... : r/linux4noobs https://www.reddit.com/r/linux4noobs/comments/95pnrb/dos2unix_command_not_found_on_cygwin_worked_fine/
- Git - git-config Documentation https://git-scm.com/docs/git-config
- Configuring Git to handle line endings - GitHub Docs https://docs.github.com/en/get-started/git-basics/configuring-git-to-handle-line-endings
- 跨平台開發--換行符號. 多人協作開發時,難免會遇到不同作業系統,一般情況下不同系統並不會影響開發,但在某… | by Jimmy | Medium https://medium.com/@okesseko/%E8%B7%A8%E5%B9%B3%E5%8F%B0%E9%96%8B%E7%99%BC-%E6%8F%9B%E8%A1%8C%E7%AC%A6%E8%99%9F-a313d96346c8
- Git 在 Windows 平台處理斷行字元 (CRLF) 的注意事項 | The Will Will Web https://blog.miniasp.com/post/2013/09/15/Git-for-Windows-Line-Ending-Conversion-Notes

留言
張貼留言