在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"
按预期工作。谢谢!