Использование echo -e в PS1 приводит к проблемам с переносом строк в оболочке

Использование echo -e в PS1 приводит к проблемам с переносом строк в оболочке

Проблемы:

Откройте командную строку:

введите описание изображения здесь

Введите букву a несколько раз:

введите описание изображения здесь

Вместо переноса на новую строку введенный текст переносится на ту же строку:

введите описание изображения здесь

Теперь начните нажимать b. Во второй раз, когда потребуется перенос строки, он перенесется на новую строку:

введите описание изображения здесь


Что является причиной такого поведения?

Использование PS1 таким образом приводит к следующему поведению:

ps1Color="\033[1;35m"
export PS1='$(echo -en $ps1Color) Baz $'

Обратите внимание, что я хочу использовать echo вместо цвета напрямую, потому что я хочу добавлять цвет условно, на основе статуса выхода предыдущей команды..

Использование цвета напрямую не приводит к такому поведению.


У меня есть вопросы:

  • Как распечатать цветовые коды для использования в PS1?используя эхо?
  • Если я хочу условно изменить цвет своей PS1, как лучше всего это сделать?
  • Почему я наблюдаю такое поведение?

Обновлять

Чтобы внести ясность, я действительно хочу сделать это с помощью Echo, потому что я хочу изменить цвет.условно.

Вот что у меня есть на данный момент:

function setPs1Colors_start () {

    local previousExit=$?

    local ps1Color="\033[1;35m"
    local ps1FailBackground="\e[41m"

    echo -en $ps1Color

    if [[ previousExit -ne 0 ]]
    then
        echo -en $ps1FailBackground
    fi

}

function setPs1Colors_end () {
    local ps1DefaultColor="\033[0m"
    echo -en $ps1DefaultColor
}

export PS1='$(setPs1Colors_start)[$(date +%b\-%d\ %k:%M)][$(versionControlInfo)\W]\$$(setPs1Colors_end) '

решение1

\033[1;35m7 символов. bashне может предположить, что эти 7 символов на самом деле имеют нулевую ширину. Если нет, он будет думать, что они имеют ширину 7 столбцов.

Он (или, скорее, readlineбазовый редактор строк, который он использует) хочет знать текущее положение на экране, поскольку он использует последовательности позиционирования курсора (вверх, вниз, влево, вправо) для перемещения курсора при использовании клавиш редактирования.

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

Также обратите внимание, что расширение подсказки в bashраспознает \eкак символ ESC, поэтому вам не нужно использовать echo -e. Вы можете просто сделать:

PS1='\[\e[1;35m\] blah $ '

Если вам нужно использовать echo, или лучше printf, вы бы сделали:

PS1='\[$(if ...; then printf "$color1"; fi)\] blah $ '

Или:

PS1='$(if ...; then printf "\[$color1\]"; fi) blah $ '

В zshэквиваленте bash's \[...\]есть %{...%}то же самое, что и в tcsh, но zshесть директивы для изменения атрибутов символов, поэтому там лучше сделать так:

PS1='%B%F{magenta}blah $ '

Для жирного пурпурного переднего плана. Он также имеет некоторые формы условных тестов, включая on $?, поэтому ваша redошибка if, green в противном случае может быть записана:

PS1='%F{%(?:green:red%)}blah%f $ '

tcshимеет %B, но не %F{color}. Так что там, вы бы использовали:

set prompt = '%{\e[1;35m%}blah $ '

В ksh88или pdkshвы бы сделали:

PS1=$(printf '\5\r\5\33[1;35m\5blah $ ')

Это определяет символ (здесь 0x5) какпобегсимвол. Затем, заключая текст между парой из них, вы сообщаете оболочке, что он невидим. Вы можете использовать любой символ, кроме 0x5, но он не должен встречаться в приглашении и, за исключением mksh, он должен игнорироваться терминалом, поскольку оболочка фактически записывает его (вместе с символом CR).

ksh93использует только одну последовательность позиционирования курсора: BS(которая перемещает курсор на одну колонку влево). Чтобы переместиться вправо, он просто перерисовывает те же символы. Поэтому ему не нужно знать позицию курсора, только ширину каждого введенного вами символа. Это работает до тех пор, пока терминал сам по себе переносится на поле (поэтому не будет работать правильно с этимterminatorнапример). Одним из побочных эффектов, если у вас есть приглашение с управляющими последовательностями, является то, что ваши позиции табуляции не будут правильно выровнены.

Связанный контент