Избегайте непечатных символов в функции для приглашения Bash


22

В приглашении Bash (переменная PS1) я вызываю функцию, чтобы потенциально добавить текст в приглашение: export PS1="\u@\h \$(my_function) \$ "

Однако функция в приглашении содержит цветовые коды ANSI, которые меняются в зависимости от выходных данных функции (иногда красный, иногда зеленый). Добавление " \[" к переменной PS1 должно исключить эти коды как непечатные, но если я сделаю echoв функции, " \[" будет напечатано буквально в приглашении.

Как я могу избежать этих цветовых кодов ANSI из функции для использования в приглашении bash?

Ответы:


34

Библиотека 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.


Примечание: Если вы используете Баш «s printfили echo -e, если текст имеет \001или \002непосредственно перед номером, вы попали в Баше ошибку , которая заставляет его есть одна цифры слишком много при обработке восьмеричным ускользает - то есть, \00142будет интерпретироваться как восьмеричная 014 (с последующим ASCII "2") вместо правильного восьмеричного 01 (с последующим ASCII "42"). По этой причине используйте шестнадцатеричные версии \x01и \x02вместо.


Это делает это! echo -e "\001\e[31m\002RED"работает как положено. Благодарность!
MidnightLightning

Извините, что воскресил ответ, но каков эквивалент тире / аш / ш?
Хош Садик

@ Боже, если они используют readline, \001и \002будут работать. В противном случае я не уверен. Например, Dash определенно не использует readline .
wjandrea

1

Вот хороший полный ответ. Я должен был сделать намного больше рыть, чтобы выяснить, куда \ 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-ветке, иначе она пустая.


0

Основываясь на ответе Гравити , следующее будет включать управляющие последовательности ANSI в ASCII 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"

В качестве бонуса, многократное выполнение функции не приведет к повторному запуску уже сброшенных управляющих кодов.


-2

Если вы хотите использовать их в приглашении, вам нужно сделать \[. Но если вы хотите использовать его в эхо, вы должны использовать \033[.


Хммм ... Добавление \ 033 [перед командой ANSI ("\ e [31m") и \ 033] после того, как кажется, что следующий напечатанный символ в приглашении не печатается.
MidnightLightning

1
Вы не хотите делать \ 033] после этого. \ 033 [31m запускает цвет, после чего вам нужно установить его обратно с помощью \ 033 [0m
Wuffers
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.