在bash PS1中设置变量

时间:2014-07-03 20:17:33

标签: bash ps1

我试图自定义我的bash提示,但我遇到了一些条件问题。

我当前的PS1看起来像这样。

export PS1="\
$PS1USERCOLOR\u\
$COLOR_WHITE@\
$COLOR_GREEN\h\
$COLOR_WHITE:\
$COLOR_YELLOW\W\
\`if type parse_git_branch > /dev/null 2>&1; then parse_git_branch; fi\`\
\`if [ \$? = 0 ]; then echo -e '$COLOR_WHITE'; else echo -e '$COLOR_RED'; fi\`\$\     
$COLOR_WHITE"
  • 前6行只设置常规PS1内容。

  • 然后第7行调用一个函数来显示当前的git分支和状态(如果适用)。

  • 第8行然后测试上一个命令的返回码,并在结尾处更改$的颜色。

  • 第9行将提示设置为白色,准备好用户的命令。

然而,第8行是响应第7行功能的返回码而不是我最初预期的上一个命令。

我已尝试在第7行之前移动第8行,并且eveything正常工作。但我不想在第7行之前排第8行,$必须在最后。

我之前尝试将变量设置为$?的值,然后像这样测试该变量

export PS1="\
\`RETURN=\$?\`\
$PS1USERCOLOR\u\
$COLOR_WHITE@\
$COLOR_GREEN\h\
$COLOR_WHITE:\
$COLOR_YELLOW\W\
\`if type parse_git_branch > /dev/null 2>&1; then parse_git_branch; fi\`\
\`if [ \$RETURN = 0 ]; then echo -e '$COLOR_WHITE'; else echo -e '$COLOR_RED'; fi\`\$\     
$COLOR_WHITE"

但这不起作用。

有人知道如何解决我的问题吗?

3 个答案:

答案 0 :(得分:4)

正确的方法是使用PROMPT_COMMAND,如下所示:

prompt_cmd () {
    LAST_STATUS=$?
    PS1="$PS1USERCOLOR\u"
    PS1+="$COLOR_WHITE@"
    PS1+="$COLOR_GREEN\h"
    PS1+="$COLOR_WHITE:"
    PS1+="$COLOR_YELLOW\W"
    if type parse_git_branch > /dev/null 2>&1; then
        PS1+=$(parse_git_branch)
    fi
    if [[ $LAST_STATUS = 0 ]]; then
        PS1+="$COLOR_WHITE"
    else
        PS1+="$COLOR_RED"
    fi
    PS1+='\$'
    PS1+="$COLOR_WHITE"
}

由于在每个提示之前评估PROMPT_COMMAND,因此您只需执行代码,按照您喜欢的方式为每个提示实例设置PS1,而不是尝试在字符串本身中嵌入延迟逻辑。

几点说明:

  1. 您必须在代码的第一行保存$?,然后才能覆盖您想要的值。
  2. 我对大部分步骤使用双引号,\$除外;如果你愿意,你可以使用PS1+="\\\$"

答案 1 :(得分:1)

此问题的标准解决方案是使用bash环境变量PROMPT_COMMAND。如果将此变量设置为shell函数的名称,则在显示每个bash提示符之前将执行所述函数。然后,在所述函数内部,您可以设置所需的任何变量。以下是我在.bashrc中几乎完全按照您的意愿行事的方式:

titlebar_str='\[\e]0;\u@\h: \w\a\]'
time_str='\[\e[0;36m\]\t'
host_str='\[\e[1;32m\]\h'
cwd_str='\[\e[0;33m\]$MYDIR'
git_str='\[\e[1;37m\]`/usr/bin/git branch --no-color 2> /dev/null | /bin/grep -m 1 ^\* | /bin/sed -e "s/\* \(.*\)/ [\1]/"`\[\e[0m\]'
dolr_str='\[\e[0;`[ $lastStatus -eq 0 ] && echo 32 || echo 31`m\]\$ \[\e[0m\]'
export PS1="$titlebar_str$time_str $host_str $cwd_str$git_str$dolr_str"

function prompt_func {
    # Capture the exit status currently in existence so we don't overwrite it with
    # any operations performed here.
    lastStatus=$?

    # ... run some other commands (which will have their own return codes) to set MYDIR
}

export PROMPT_COMMAND=prompt_func

现在bash将在显示每个新提示之前运行prompt_func。在lastStatus中捕获前一命令的退出状态。由于git_strdolr_str等是使用单引号定义的,因此当bash取消引用lastStatus时,会重新评估变量(包括PS1)及其中的命令。< / p>

答案 2 :(得分:0)

解决了!

我需要使用PROMPT_COMMAND变量来设置RETURN变量。 PROMPT_COMMAND是在加载PS1之前调用的命令。

我的脚本现在看起来像

PROMPT_COMMAND='RETURN=$?'

export PS1="\
$PS1USERCOLOR\u\
$COLOR_WHITE@\
$COLOR_GREEN\h\
$COLOR_WHITE:\
$COLOR_YELLOW\W\
\`if type parse_git_branch > /dev/null 2>&1; then parse_git_branch; fi\`\
\`if [[ \$RETURN = 0 ]]; then echo -e '$COLOR_WHITE'; else echo -e '$COLOR_RED'; fi\`\$\     
$COLOR_WHITE"