MSYS2 疑難雜症


這一篇會不定期附加新的問題解決方法. Enjoy it!

bash 介面亂碼


如果你的 bash shell 設定使用 locale:zh_TW, Character set:UTF-8, 那在使用一些 windows 的指令時, 往往都會出現亂碼, 你可以使用以下的指令 (將 windows console 切換為 utf-8 字集), 把大部份的問題解決:

cmd //C "chcp 65001"
  • 如果不想每次開啟bash都要重新打一遍, 可以把它加在自己的.bashrc裡.
    echo 'cmd //C "chcp 65001"' >> ~/.bashrc
    
  • 如果你想直接用熟悉的 windows 編輯工具來修改它, 那麼檔案.bashrc的目錄路徑應該是在 C:\Users\<自己的 windows 帳號名稱>底下.
  • 還有要注意一下: 該目錄下是否也有.profile檔. 一般.bashrc是經由.profile呼叫的.

至於為什麼更換了 code page 之後只是解決大部份的問題呢? 那是因為有部份指令輸出的資料並非來自指令本身, 例如: ipconfig輸出的介面卡中文名稱有些還是用 big5 編碼. 遇到這種資料 Windows CMD看得懂, 但是bash看不懂啊!

不過, 你也可以利用 winpty 指令, 來包裹原始的 windows 指令 (sorry, 僅限於.exe指令. .com 指令包裹後會出現錯誤), winpty可以完美的將原本的 big5 編碼輸出訊息, 轉換成正確的 utf-8 編碼訊息並顥示出來. (請參看 利用 winpty 指令 段落)


另一種讓 windows 指令可以正確顯示的方法是使用 Windows(7) 中文版預設的 950 字集, 如下圖 (選用第一項 default 即可):

字集設定

使用 chcp 950 避免 windows 指令輸出的中文亂碼

不過現今大多數程式都已經偏向採用 utf-8 字集了, 這會使得你在處理有使用 utf-8 中文的程式遇到困難. 所以我比較建議使用上面的第一種方法. 或者你也可以臨時再開一個 bash, 改成使用 950 字集

指令: ln


請你不要使用 MSYS2 原本的ln指令, 它會進行拷貝動作而不是連結.

MSYS2 承襲自 cygWin 無法在 Windows 不支援連結功能的舊檔案系統上 (FAT, FAT32, exFAT32) 提共連結 (link) 的功能. 雖然 NTFS 檔案系統已經具備連結功能 (NTFS v3.0以上), 但 MSYS2 對於連結的處理能力依然不完整. 不過, 我們可以利用 windows 原本的指令來達成部份功能:

  • Windows 7/8/10 都有提供mklink指令可以在 NTFS 檔案系統上完成連結的動作.
  • Windows XP 則需要下載 Windows 2003 Resource kit 並將指令名稱改為linkd.

關於這個問題的詳細說明在這個連結: git for windows 在 github 上有關 symbolic links 的說明文件.

如果你想要整合度好一些, 則可以參考 stackoverflow 上的這一段解答所提供的作法: git-bash-shell-fails-to-create-symbolic-links

另外: 如果你在 VM 上使用 bash (不論是 MSYS2 或者 git for windows 的) 則遠端的連結還有一些額外的問題.

  • 雖然 guest OS (Windows) 本身對於本地端或者是遠地端的連結都可以正確連結. 但刪除遠地端的連結會將原本的內容刪除, 而不是移除連結本身.
  • 同時, 經由 bash shell 我們只能存取本地端的連結; 遠地端的連結則都無法存取 (access).
  • 所謂本地端指的是 guest OS 自身的磁碟空間. 而所謂遠地端就是經由網路協定存取的, 不論是 host OS 分享給 guest OS 的, 或者經由其他網路主機分享給 guest OS 的.

總之如果要在 VM 上使用連結, 你得小心測試無誤了再使用.

指令: more


MSYS2 有less指令, 沒有more指令. 請用less來替代more. 真的不習慣或者有需要的話可以建一個 link 來替代. 指令如下:

cmd //C 'mklink D:\Git\usr\bin\more.exe D:\Git\usr\bin\less.exe'

請把其中的D:\Git更換成你的 Git for windows (或者是 MSYS2) 的安裝目錄.

指令: chmod


(2019/01/09) 今天發現 msys2 的 chmod 指令竟然無效: 想要為 .sh 檔加執行權限, 竟然一直加不上去 (雖然是一樣可以執行). Google 大神拜了二下下總算解決. 原來 cygwin 移植時引發的問題. 有人建議修改/etc/fstab/的權限由noacl改為acl即可, 不過個人認為這不是好方法: 因為原本沒有加執行權限時, .sh 檔和 .py 檔已經可以執行了, 我只是想要為 ls 的輸出上色. 所以比較好的方案是: 修改檔案的第一行. 如果是 shell script, 就加上這一行
#!/usr/bin/bash
(哈! 以前一直不知道這一行的用途到底是什麼, 現在總算明白.)

如果是python程式, 則換成
#!/usr/bin/python

不過要注意的是/usr/bin/...不是依樣畫葫蘆就好, 必需真實的有該指令存在才行啊! 否則像是要執行.py檔, 你想直接輸入你的.py檔名, 省略指令最前面的python , 這樣是沒辦法執行的啊! 其實它的意思是叫 shell 用我指定的那一個指令來執行 (或是解譯) 檔案的內容.

不過有一個替代辦法是指定指令但是不指定路徑. 像這樣:
#! python

還有, 這一行務必要放在第一行.

指令: git 中文路徑/檔名亂碼


如果你的git status, git log, git diff...等指令輸出時, 中文路徑/檔名出現的是亂碼 (utf-8 編碼的怪字), 請以下列指令修改 git 的設定.

$ git config --global core.quotepath false
git for windows 中文亂碼

git for windows 中文路徑/檔名亂碼

目前我使用過的版本 (git for windows 2.14.1 ~ 2.20.1) 都只要修改這個即可. 如果你用的版本還是有中文亂碼的問題, 又不便更新的話, 其他可能需要更動的部份還有:

$ git config --global i18n.commit.encoding utf-8    # 提交信息的編碼
$ git config --global i18n.logoutputencoding utf-8  # log 的編碼
$ git config --global gui.encoding utf-8            # 圖形界面的編碼

上述這些設定更動你也可以直接修改檔案C:\ProgramData\Git\config. 我們需要更動的部份顯示如下:

[core]
    quotepath = false
[gui]
    encoding = utf-8
[i18n]
    commitencoding = utf-8
    logoutputencoding = utf-8

另外, 如果git log指令的輸出也有亂碼的話, 需要修改less指令 (訊息分頁指令) 的預設編碼:

$ export LESSCHARSET=utf-8

這個修改可以加在./bashrc裡.

利用 winpty 指令(2019/04/10)


有許多原本 linux/unix 的指令或者程式需要搭配正確的 tty 才能正常運作. 通常作這類程式移值到 windows 時會 console 沒有輸出或者沒有輸入, 預到這種情況最簡單的方法即是 '利用 winpty 提供它執行時所需要的 tty 環境'. 方法很簡單: 在原本使用的指令前面加上 winpty 即可. 例: winpty /path/to/python.exe abcxyz.py

另外有一個可以大推 winpty 的點是, 利用它來包裹 windows 原生的指令, 就不會出現亂碼的現象了.

winpty

使用 winpty 包裹 windows 原生的指令就沒有亂碼了

相關連結

連結


MagicJackTing 發表在 痞客邦 留言(0) 人氣()