Жиль определил вашу главную проблему, но я хотел попытаться объяснить это по-другому.
Bash интерпретирует экранирование специальных приглашений только перед раскрытием любых переменных в приглашении. Это означает, что использование \e
переменной, развернутой из приглашения, не работает, даже если она работает непосредственно в PS1
.
Например, это работает как ожидалось и дает красный текст:
PS1='\e[1;31m this is in red '
Но это не так, он просто помещает литерал \e
в приглашение:
RED='\e[1;31m'
PS1="$RED not in red "
Если вы хотите сохранить экранирование цвета в переменных, вы можете использовать ANSI-C quoting ( $'...'
), чтобы поместить буквенный escape-символ в переменную.
Чтобы сделать это, вы можете изменить свое определение GREEN
, RED
и NONE
, таким образом , их значение является фактической последовательностью выхода.
GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
Если вы сделаете это, ваш первый PS1
с одинарными кавычками должен работать:
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Однако тогда у вас возникнет вторая проблема.
Попробуйте запустить это, затем нажмите Up Arrow, затем Home, и ваш курсор не вернется к началу строки.
Чтобы исправить это, измените PS1
на включение \[
и \]
вокруг цветовых escape-последовательностей, например
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
Вы не можете использовать get_exit_status
здесь должным образом, так как его вывод содержит как печатные (код выхода), так и непечатаемые символы (цветовые коды), и нет возможности правильно пометить его в приглашении. Помещение \[...\]
будет помечено как непечатное полностью, что не правильно. Вам нужно изменить функцию, чтобы она печатала только правильный цветовой код, а затем заключить его \[...\]
в подсказку.
\[
есть\1
и\[
есть\2
. Это соответствует некоторойRL_PROMPT_{START,END}_IGNORE
вещи readline , которая просит ее игнорировать байты при подсчете длины подсказки на экране. См. Lists.gnu.org/archive/html/bug-bash/2015-08/msg00027.html .\]
это\2
? И ты имеешь ввиду, для чего это нужно${exitStatus}
? Моя точка зрения заключалась в том, что${exitStatus}
она не содержит непечатаемых символов, поэтому bash должен уметь правильно определять, на сколько символов он перемещает подсказку без\[
и\]
в\[${exitStatus}\]
.\e
и\033
(и\[
/\]
,,\u
и\h
) из приглашения, он просто делает это перед раскрытием переменных. ТакPS1='\e[1;31m red'
работает,red='\e[1;31m'; PS1='$red red'
нет.Когда вы запускаете
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
,PS1
переменная устанавливается на${RED}\h $(get_path) ${exitStatus}${NONE}
, где только\h
последовательность подсказок. После того, как последовательности подсказок расширены (дают${RED}darkstar $(get_path) ${exitStatus}${NONE}
), оболочка выполняет обычные расширения, такие как переменные. Вы получите отображаемое приглашение, которое выглядит следующим образом\e[1;31mdarkstar PATH 0\e[m
. Ничто на этом пути не расширяет\e
последовательности до реальных escape-символов.При запуске
PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "
, тоPS1
переменная устанавливается\e[1;31m\h PATH 0\e[m
. ПеременныеRED
,exitStatus
иNONE
раскрываются во время назначения. Тогда подсказка содержит три оперативные управляющие последовательности (\e
,\h
и\e
снова). На этом этапе нет переменных оболочки для расширения.Для того, чтобы увидеть цвета, вам нужно, чтобы переменные цвета содержали реальные escape-символы. Вы можете сделать это следующим образом:
$'…'
Расширяет восьмеричные последовательности с обратной косой чертой и некоторые последовательности букв с обратной косой чертой, такие как\n
, но не включая\e
. Я сделал три других изменения в вашем приглашении:\[…\]
вокруг непечатаемых последовательностей, таких как команды изменения цвета. В противном случае ваш дисплей будет искажен, потому что bash не может определить ширину приглашения.\w
является встроенной escape-последовательностью для печати текущего каталога$?
в подсказке, если у вас нетPROMPT_COMMAND
в первую очередь.источник
PS1
это неправильно, но совет использования$'...'
дляRED
иGREEN
должны сделать его работу с помощью кендырь - хPS1
.Пытаться:
источник
Вот подход, который я использовал, он избегает использования
PROMPT_COMMAND
.Тогда мой
$PS1
следующий:источник
$?
может иметь целое число, вам действительно следует использоватьprintf '%b' "$GREEN"
вместо этого. Кроме того, избегайте использования имен функций с префиксом__
или_
как они используются bash-complete.Здесь вы идете - Это работает для меня (TM) в Ubuntu и других Linux (Linuxen?).
Причиной включения обнаружения кода выхода
$PS1
является то, что один хост имеет доступ только для чтения$PROMPT_COMMAND
до чтения .bashrc.источник
Ведь
PROMPT_COMMAND
чище определить функцию и использовать это:источник