4

我正在尝试自定义我的 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 行,并且一切正常。但我不希望第 8 行在第 7 行之前,$必须在最后。

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

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"

但这不起作用。

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

4

3 回答 3

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+="\\\$"如果你喜欢,你可以使用。
于 2014-07-03T21:08:30.877 回答
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_str,dolr_str等是用单引号定义的,所以lastStatus当 bash 取消引用时,它们里面的变量(包括 )和命令会被重新计算PS1

于 2014-07-03T20:37:57.583 回答
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"
于 2014-07-03T20:28:19.217 回答