Git for Windows 的 Bash 有一個很實用的功能,如果當前目錄處於 Git 倉庫中,那麼命令行中會顯示當前 Git 分支的名稱(見下圖)。 然而原版的 MSYS2 Bash 沒有這個功能(見下圖),不過我們可以自己動手配置出相同的效果。 配置方法 打開 MSYS2 的家目錄,找到 . ...
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
函數),我用的是這個回答中的方法。