2011-08-21 52 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 
相关问题