在 Bash 提示符的函数中转义非打印字符

在 Bash 提示符的函数中转义非打印字符

在 Bash Prompt(PS1 变量)中,我调用一个函数来向提示符中添加文本:export PS1="\u@\h \$(my_function) \$ "

但是,提示中的函数包含根据函数输出而变化的 ANSI 颜色代码(有时为红色,有时为绿色)。将“ \[”添加到 PS1 变量应该会将这些代码转义为不可打印,但如果我echo在函数中执行此操作,“ \[”会在提示中逐字打印。

如何在函数中转义这些 ANSI 颜色代码以在 Bash 提示符中使用?

答案1

阅读行库接受\001\002ASCIISOH 和 STX) 作为不可打印的文本分隔符。这些也适用于使用阅读行

lib/readline/display.c:243狂欢源代码:

243 /* Current implementation:
244         \001 (^A) start non-visible characters
245         \002 (^B) end non-visible characters
246    all characters except \001 and \002 (following a \001) are copied to
247    the returned string; all characters except those between \001 and
248    \002 are assumed to be `visible'. */

狂欢-特定\[并且\]实际上被翻译为\001和。\002y.tab.c:7640


注意:如果您使用狂欢或,如果你的文本在数字前有 或 ,你会printf碰到一个echo -e\001\002狂欢处理八进制转义时,错误导致它多吃了一个数字 - 也就是说,\00142将被解释为八进制 014(后跟 ASCII“2”),而不是正确的八进制 01(后跟 ASCII“42”)。因此,请使用十六进制\x01版本\x02

答案2

这是一个很好的完整答案。我不得不做更多的挖掘才能弄清楚 \001 等应该去哪里。希望这能有所帮助。

# Color prompt for git
reset=$(tput sgr0)
boldgreen=$(tput setaf 2)$(tput bold)
cyan=$(tput sgr0)$(tput setaf 6)
boldred=$(tput setaf 1)$(tput bold)
boldwhite=$(tput setaf 7)$(tput bold)
boldyellow=$(tput setaf 3)$(tput bold)

PARENCLR=$'\001\e[0;36m\002'
BRANCHCLR=$'\001\e[1;33m\002'

alias branchname="git branch 2>/dev/null | grep '*' | sed 's/* \(.*\)/ ${PARENCLR}(${BRANCHCLR}\1${PARENCLR}\)/'"

GIT_STATUS='$(branchname)'

PROMPT_CHAR="\$"
PS1="\[$boldgreen\]\u\[$cyan\]::\[$boldred\]\h \[$cyan\]{\[$boldwhite\].../\W\[$cyan\]}\[$reset\]$GIT_STATUS\[$reset\]$PROMPT_CHAR "

按照我在这里的设置方式,只有当您在 git 分支中时,git 分支括号才会出现,否则它是空白的。

答案3

基于gravity 的回答,以下将用 ASCII SOH( ^A) 和STX( ^B) 括起 ANSI 控制序列,它们分别等同于\[\]

function readline_ANSI_escape() {
  if [[ $# -ge 1 ]]; then
    echo "$*"
  else
    cat  # Read string from STDIN
  fi | \
  perl -pe 's/(?:(?<!\x1)|(?<!\\\[))(\x1b\[[0-9;]*[mG])(?!\x2|\\\])/\x1\1\x2/g'
}

使用方式如下:

$ echo $'\e[0;1;31mRED' | readline_ANSI_escape

或者:

$ readline_ANSI_escape "$string"

另外,多次运行该函数不会重新转义已经转义的控制代码。

答案4

如果您想在提示中使用它们,那么您确实需要执行\[。但是如果您想在回显中使用它,您必须使用\033[

相关内容