Подтвердить что ты не робот

Пользовательское приглашение Bash переписывает себя

Я использую пользовательское приглашение bash для отображения ветки git.

Все находится в /etc/bash/bashrc:

function formattedGitBranch {
    _branch="$(git branch 2>/dev/null | sed -e "/^\s/d" -e "s/^\*\s//")"
    # tried these:
    echo -e "\e[0;91m ($_branch)"                       
    echo -e "\e[0;91m ($_branch) \e[m"                  
    echo -e $'\e[0;91m'"($_branch)"
    echo "($_branch)"                                   
    echo "$(tput setaf 2) ($_branch) $(tput setaf 9)"
    printf "\e[0;91m ($_branch)"
}

# color is set before function call
PS1='\[\033[01;34m\] \[\033[0;91m\]$(formattedGitBranch) \$\[\033[00m\] '
# color is set inside function
PS1='\[\033[01;34m\] $(formattedGitBranch) \$\[\033[00m\] '

Проблема в том, что когда я устанавливаю цвет для $_branch в функции, моя подсказка будет перезаписана при достижении EOL:

mmmmmmmmmmmmp/rainyday.js (master) $ mmmmmmmm

Пробовал все возможные варианты обозначения tput, printf, $''.

Я решил проблему, установив цвет только в PS1:

ad@gentoo /tmp/rainyday.js (master) $ mmmmmmm

Но..

  • Я хотел бы знать, почему он переписывает мое приглашение
  • Как исправить эту проблему при использовании функции

Я использую Gentoo Linux. GNU bash, verze 4.2.37(1)-release (i686-pc-linux-gnu)

4b9b3361

Ответ 1

1) Я хотел бы знать, почему он переписывает мое приглашение

Поскольку все символы, не подлежащие печати, должны быть экранированы \[ и \] иначе readline не может отслеживать курсор правильно позиционировать.

Вы должны поместить \[ и \] вокруг любых escape-последовательностей без печати в вашем приглашении.
Без \[ \] bash будет считаться, что байты, составляющие escape-последовательности для цветовых кодов, фактически занимают место на экране, поэтому bash не сможет узнать, где находится курсор.

\[ Начните последовательность непечатаемых символов. (например, последовательности выделения цвета). Эта      позволяет bash правильно рассчитать перенос слов.

\] Завершить последовательность непечатаемых символов. - BashFAQ

... обратите внимание на экраны для непечатаемых символов, это гарантирует, что readline может правильно отслеживать позицию курсора. - ss64.com

2) Как исправить эту проблему при использовании функции

Если вам действительно нужно/нужно устанавливать цвета внутри функции, выход которой используется в PS, у вас есть 2 варианта:

echo -e не знает bash \[ \], поэтому вам нужно заменить их на \001 и \002 Коды управления ASCII для разграничения непечатаемых символов от печати:

function formattedGitBranch { echo -e "\001\e[0;91m\002 ($_branch)"; }
PS1='$(formattedGitBranch) '

Ответ 2

Строкам типа \e[0;91m требуется дополнительное цитирование, чтобы предотвратить bash от его длины.

Вставьте эти строки из formattedGitBranch в \[ и \] as, \[\e[0;91m\]

Вы сделали это правильно в других местах. Просто пропустил его в формате gitBranch.

Ответ 3

Вы должны позаботиться о непечатаемом символе внутри [\ и /], иначе вы могли бы получить курсор в верхней части командной строки, как и в самом вопросе, поэтому я нашел что-то и просто поделился им: -

Чтобы получить курсор после вывода PS1 в той же строке:

После

несколько примеров:

PS1='[\[email protected]\h:\w]\$
PS1='[\[\033[0;32m\]\[email protected]\h:\[\033[36m\]\W\[\033[0m\]]\$ '

Ссылка: синтаксис для bash PS1