具有背景色的Bash提示符延伸到行末

4

现在是我调整bash提示的时间(总有一天不得不这样做……)。

我试图获得一个两行提示:

  • 第一行包含位置信息,并且背景色延伸至行末
  • 第二行包含时间和上一个命令的退出代码

我已经接近成功了,但我无法破解“背景色延伸至行末”这一部分。还差一点。

从几个来源汇集信息,最重要的是从这里这里,我得到这个结果(终端截图)

正如你所看到的,COLUMNS计算有些问题:

  • 它没有达到行末
  • 它取决于第一行的文本长度
  • 当到达终端底部时会变得更糟;那时它会到达行末;错误的行……
  • 另一个奇怪的事情是:微小的[ ]只有在输入命令后才出现在第二个提示行的两侧

这是我的bashrc代码:

PROMPT_COMMAND=__prompt_command
__prompt_command()
{
    local EXIT="$?" 

    local Red='\[\033[1;38;5;9m\]'
    local Green='\[\033[1;38;5;10m\]'
    local Gray='\[\033[0;38;5;248m\]'
    local BgBlue='\[\033[48;5;253;1;38;5;12m\]'
    local BgPurple='\[\033[48;5;253;1;38;5;93m\]'
    local None='\[\e[0m\]'

    PS1="${BgPurple}\u@\h:${BgBlue}\$PWD"

    printf -v TC_SPC "%${COLUMNS}s" ''

    COLUMNS=$(tput cols)
    PS1=`echo $PS1 | sed "s/$/$TC_SPC/; s/^\\(.\\{${COLUMNS}\\}\\) */\\1/"`

    PS1+="\n${Gray}\D{%F %T}"

    if [ $EXIT != 0 ]; then
        PS1+=" ${Red} O_o ${None}"      # Add red if exit code non 0
    else
        PS1+="${Green} ^_^ ${None}"
    fi
}

我试过更多的黑客攻击,但没有成功。

哦,还有一种更复杂的sed位版本,我也尝试过:

    PS1=`echo $PS1 | sed "s/$/$TC_SPC/; s/^\\(\\(\\o33\\[[0-9;]*[a-zA-Z]\\)*\\)\\([^\o033]\\{${COLUMNS}\\}\\) */\\1\\3/"`

结果不同(终端截图),但仍然不好。

此时我需要任何帮助!

2个回答

4
这是可行的解决方案,感谢Eric提供的“擦除至行尾”的提示。
PROMPT_COMMAND=__prompt_command # Func to gen PS1 after CMDs
__prompt_command()
{
  local EXIT="$?"             # This needs to be first (retrieves last commmand exit code)

  local Red='\[\033[1;38;5;9m\]'
  local Green='\[\033[1;38;5;10m\]'
  local Gray='\[\033[0;38;5;248m\]'
  local BgBlue='\[\033[48;5;253;1;38;5;12m\]'
  local BgPurple='\[\033[48;5;253;1;38;5;93m\]'
  local None='\[\e[0m\]'

  PS1="${BgPurple}\u@\h:${BgBlue}\$PWD"
  PS1+="\033[K"             # erase to end of 1st line (background color stays)

  PS1+="\n${Gray}\D{%F %T}\a"

  if [ $EXIT != 0 ]; then
    PS1+="${Red} O_o ${None}"   # Add red if exit code non 0
  else
    PS1+="${Green} ^_^ ${None}"
  fi
  PS1+="\033[K"             # erase to end of 2nd line (no more background color)
}

这里是结果(终端截图)(点击查看)。又一个快乐的提示拥有者...


2

替代方案:

printf -v TC_SPC "%${COLUMNS}s" ''

COLUMNS=$(tput cols)
PS1=`echo $PS1 | sed "s/$/$TC_SPC/; s/^\\(.\\{${COLUMNS}\\}\\) */\\1/"`

使用:

PS1+=$'\033[K' #erase to end of line

谢谢,Eric。太完美了,而且如此简单...我不得不在这两行之后添加这个,第二行是为了解决当达到终端底部时出现的问题。出于好奇,你建议中的'$'是什么意思?我试过带和不带它,好像效果都一样。 - Peyo61
在bash中,$'STRING'类似于单引号字符串,但会赋予反斜杠转义序列特殊含义。在这种情况下,\nnn 会被替换为“其值为八进制值nnn(一到三位数字)的8位字符”。 八进制033是转义字符。请参阅man bash并搜索$'以获取完整列表。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接