在Bash提示符(PS1变量)中,我正在调用一个函数来向提示添加文本: export PS1="\u@\h \$(my_function) \$ "
但是,提示中的函数包含ANSI颜色代码,这些代码根据函数的输出而变化(有时是红色,有时是绿色)。添加“ \[ “PS1变量应该将这些代码转义为非打印,但是如果我这样做的话 echo 在功能中,“ \[ “在提示中按字面打印。
如何从函数中转义这些ANSI颜色代码以用于bash提示符?
在Bash提示符(PS1变量)中,我正在调用一个函数来向提示添加文本: export PS1="\u@\h \$(my_function) \$ "
但是,提示中的函数包含ANSI颜色代码,这些代码根据函数的输出而变化(有时是红色,有时是绿色)。添加“ \[ “PS1变量应该将这些代码转义为非打印,但是如果我这样做的话 echo 在功能中,“ \[ “在提示中按字面打印。
如何从函数中转义这些ANSI颜色代码以用于bash提示符?
Answers:
该 的ReadLine 图书馆接受 \001 和 \002 (ASCII SOH和STX )作为不可打印的文本分隔符。这些也适用于任何使用的应用程序 的ReadLine 。
从 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 和 \002 在 y.tab.c:7640。
注意:如果您使用 庆典 的 printf 要么 echo -e,如果你的文字有 \001 要么 \002 在一个数字之前,你会遇到一个 庆典 处理八进制转义时导致它吃掉一个数字的错误 - 也就是说, \00142 将被解释为八进制014(后跟ASCII“2”),而不是正确的八进制01(后跟ASCII“42”)。因此,请使用十六进制版本 \x01 和 \x02 代替。
这是一个很好的完整答案。我不得不做更多的挖掘来弄清楚\ 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分支括号,否则它是空白的。
基于 grawity的答案 ,以下将用ASCII括起ANSI控制序列 SOH ( ^A )和 STX ( ^B )相当于 \[ 和 \] 分别:
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"
作为奖励,多次运行该功能将不会重新逃脱已经转义的控制代码。
如果要在提示中使用它们,则需要执行此操作 \[。但是如果你想在回声中使用它,你必须使用它 \033[。
echo -e "\001\e[31m\002RED"按预期工作。谢谢!