Git for Windows 的 Bash 有一個很實用的功能,如果當前目錄處於 Git 倉庫中,那麼命令列中會顯示當前 Git 分支的名稱(見下圖)。
然而原版的 MSYS2 Bash 沒有這個功能(見下圖),不過我們可以自己動手設定出相同的效果。
開啟 MSYS2 的家目錄,找到 .bashrc
檔案,在其中插入以下程式碼:
function parse-git-branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
function prompt-sign() {
net session > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "#" # administrator
else
echo "$" # common user
fi
}
export PS1="\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[35m\]$MSYSTEM \[\e[33m\]\w\[\e[36m\]\$(parse-git-branch)\012\[\e[0m\]$(prompt-sign) "
接著,關閉並重新開啟命令列視窗,或者在命令列中執行 source ~/.bashrc
命令,即可看到更改後的效果(見下圖)。
上述程式碼通過修改 PS1
這個 shell 環境變數來設定命令提示字元,PS 是 prompt string 的縮寫。MSYS2 的 PS1
的預設值是 \[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[35m\]$MSYSTEM\[\e[0m\] \[\e[33m\]\w\[\e[0m\]\n\$
。在 PS1
中,以反斜槓開頭的字元有特殊含義,例如:
\u
:使用者名稱\h
:主機名\w
:當前目錄\n
:換行\$
:對 root 使用者顯示 #
,對普通使用者顯示 $
更多相關內容參見 Controlling the Prompt (Bash Reference Manual)。
PS1
支援用 ANSI 跳脫序列(ANSI escape code)設定文字的顏色,詳見 ANSI escape code - Wikipedia。
瞭解了 PS1
的相關規則後,自定義命令提示字元就不是一件難事了。寫一個獲取 Git 分支名稱的函數 parse-git-branch
,然後用 \$(parse-git-branch)
將分支名稱插入 PS1
中即可。請注意雙引號字串中 $(expr)
和 \$(expr)
的區別,如果用的是 $(expr)
語法,則只會在第一次讀取變數時對 expr
求值一次,如果用的是 \$(expr)
語法,則每次讀取變數時都會對 expr
求值。由於我們希望每次更改目錄後都重新讀取 Git 分支的名稱,因此應使用 \$(expr)
語法。
到了這裡你會碰到 MSYS2 的一個 BUG,在 \$(parse-git-branch)
之後使用 \n
換行會報如下的錯誤:
bash: unexpected EOF while looking for matching `)'
這個 Stack Overflow 回答給了一種變通的辦法,使用 \012
(換行符的 ASCII 碼)來代替 \n
即可。
接下來你會碰到 MSYS2 的另一個 BUG。正常來說,當以管理員身份執行 MSYS2 Bash 時會顯示一個 #
(見下圖),當以普通使用者身份執行時則顯示一個 $
,這與 Linux Bash 面對 root 使用者/普通使用者的行為十分相似。
前文提到,可以在 PS1
中使用 \$
為 root 使用者和普通使用者顯示不同的提示符號。但是不知何故 MSYS2 不支援這個功能,始終顯示的是 $
,所以需要額外寫一個函數判斷當前是否為管理員身份(即上面的 prompt-sign
函數),我用的是這個回答中的方法。