Проблемы:
Откройте командную строку:
Введите букву 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;35m
7 символов. 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
например). Одним из побочных эффектов, если у вас есть приглашение с управляющими последовательностями, является то, что ваши позиции табуляции не будут правильно выровнены.