2011-08-21 49 views
4

我是Bash編程的新手,我正在創建一個自定義Bash命令提示符。我的目標是創建一個提示,當它們與我通常使用的不同時,它只顯示登錄名和主機名。我還希望在Git版本控制下的目錄中追加當前的Git分支到命令提示符。

我想登錄和主機名部分綠色,目錄路徑藍色,Git分支部分粉紅色和分隔符(:和$字符)爲白色。但是,當以前執行的命令返回零以外的任何東西時,我想爲$ separator紅色着色。無顏色的一般格式如下所示:

[email protected]:~/current/path:branchname$ 

唯一必需的部分是目錄路徑和$字符。下面是我爲我的的.bashrc文件編寫的代碼:

MYNAME="gwen" 
MYHOST="gwen-laptop" 

RED="\[\033[31m\]" 
WHITE="\[\033[0m\]" 
GREEN="\[\033[01;32m\]" 
BLUE="\[\033[01;34m\]" 
PINK="\[\033[01;35m\]" 

DOLLAR="if [ \$? = 0 ]; then echo ${WHITE}\$; else echo ${RED}\$${NORMAL}; fi" 
GITBRN='$(__git_ps1 "\033[0m:\033[01;35m%s")' 

USERNM="if [ \u != ${MYNAME} ]; then whoami; fi;" 
HOSTNM="if [ \h != ${MYHOST} ]; then echo -n @; hostname; fi;" 
COLONM="if [ \u != ${MYNAME} ] || [ \h != ${MYHOST} ]; then echo -n :; fi;" 

PS1="${GREEN}\`${USERNM}\`\`${HOSTNM}\`${WHITE}\`${COLONM}\`${BLUE}\w${GITBRN}\`${DOLLAR}\` " 

此代碼滿足我所有的要求,除了它葉子$字符在任何時候都白,不着色它在紅適當的時間。 (我懷疑問題在於DOLLAR中的「\ $?」引用了先前執行的命令,但是在構造PS1時最後執行了DOLLAR,因此之前的執行語句不再是PS1構造開始之前運行的命令;它是這是爲了創建命令提示符而執行的。)我是不知道如何解決這個問題

此代碼很難看,需要重構。我試圖將所有的顏色代碼移動到它們自己的變量中,但是當我在GITBRN的代碼中使用這些顏色變量時,事情變得不合時宜,所以我最終使用了文字顏色。

我花了整整一天的時間試圖讓這段代碼正常工作,而且我想我現在在這裏沒有任何地方。任何建議如何讓這個美元符號在適當的時候變成紅色,將不勝感激。我也願意重新構建代碼,使其更清晰,更具可讀性。

P.S.我是Ubuntu Linux(Lucid Lynx)用戶。

+0

與您手邊的問題無關:我相信這足以做到if(hostnamecondition);然後HOSTNM ='';其他HOSTNM =「@ $(主機名)」; fi'或類似的東西。我不認爲主機名通常會改變:當你ssh到另一臺機器時,你在那裏產生一個新的bash,這將再次運行你的代碼。 每次顯示提示時都不檢查主機名將會有輕微的性能優勢。 –

+0

這裏的問題是,你的提示定義包含執行的命令,它會在運行後設置'$?'。您只需要將其複製到自定義變量中,但我無法完成範圍問題,因此下面的答案仍然是現在最好的解決方案。 – IMSoP

回答

3

使用PROMPT_COMMAND變量,該變量在每個主提示符之前根據bash手冊頁執行。

例如(這還沒有工作,我試圖得到它的工作的權利,但我認爲這是可能的):

PROMPT_COMMAND="if [ \$? = 0 ]; then DOLLAR="${WHITE}\$${NORMAL}"; else DOLLAR="${RED}\$${NORMAL}"; fi" 

編輯:由於與執行挫折命令和非打印字符PS1\[\]有時會打印出來,而不是用作提示PS1),我想出了這個(用您的提示替換...):

PROMPT_COMMAND='if [ $? = 0 ]; then DOLLAR_COLOR="\033[0m"; else DOLLAR_COLOR="\033[31m"; fi' 
PS1='...\[$(echo -ne $DOLLAR_COLOR)\]$\[\033[m\] ' 

當然,使用$()你可以把你的內心PS1喜歡的任何部分的這個,而不是使用PROMPT_COMMAND,我只是喜歡它所以這種方式PROMPT_COMMAND包含邏輯和PS1包含顯示命令。

+0

這是一個好主意!我不知道這個PROMPT_COMMAND的存在。謝謝! –

+0

@Gwen Avery這是一個整潔的想法,我正在考慮將它用於我自己:) – jtbandes

2

我得到它的工作:

PROMPT_COMMAND='if [ $? = 0 ]; then PS1="\[\e[32;1m\]\[email protected]\[\e[0m\e[30;47m\]\H\[\e[0m\]:\[\e[34;1m\]\w\[\e[0m\]$ "; else PS1="\[\e[31;1m\]\[email protected]\[\e[0m\e[31;47m\]\H\[\e[0m\]:\[\e[31;1m\]\w\[\e[0m\]$ "; fi' 

enter image description here

站在@jtbandes的sholders。 @jtbandes是這個創意的原創作者。

+0

您認爲只有在命令失敗時才能顯示紅色** **而不是當您按下輸入時一個空的命令行? –

1

這裏是Alexsandr's answer修改爲僅當命令失敗時才顯示紅色,而不是按照Stéphane所要求的在空白命令行上按回車鍵。

trap 'PREVIOUS_COMMAND=$THIS_COMMAND; THIS_COMMAND=$BASH_COMMAND' DEBUG 
read -r -d '' PROMPT_COMMAND << 'END' 
    if [ $? = 0 -o $? == 130 -o "$PREVIOUS_COMMAND" = ": noop" ]; then 
     PS1='\[\e[32;1m\]\[email protected]\[\e[0m\e[30;47m\]\H\[\e[0m\]:\[\e[34;1m\]\w\[\e[0m\]$ ' 
    else 
     PS1='\[\e[31;1m\]\[email protected]\[\e[0m\e[31;47m\]\H\[\e[0m\]:\[\e[31;1m\]\w\[\e[0m\]$ ' 
    fi 
    : noop 
END 
相關問題