Bash подсказка и эхо цвета внутри функции
У меня это в моем .bashrc:
LIGHTGREEN="\[\033[1;32m\]"
LIGHTRED="\[\033[1;31m\]"
WHITE="\[\033[0;37m\]"
RESET="\[\033[0;00m\]"
function error_test {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
PS1="\u\$(error_test)@\w$RESET \$ "
Это, похоже, делает вывод оболочки точно:
username\[\]@~/
В моем приглашении отображается экранирование [и] вокруг цветовых кодов. Если я удаляю escape-коды из цветов, которые он использует, но тогда bash обтекание строк происходит неудачно.
Обратите внимание, что если do PS1="LIGHTGREEN - whatever - $RESET"
работает, а [и] не сбрасываются. Тем не менее, я хочу сделать это внутри функции, которая, кажется, проблема.
Я не могу найти хорошую документацию по этому вопросу. man echo
даже не перечисляет параметр a -e. bash похоже, что у него много недокументированных знаний о handmedown.
Ответы
Ответ 1
Я нашел эту тему в поиске ответа, как установить цвет bash с экранированием \[ \]
из bash.
На самом деле есть решение. bash позволяет генерировать приглашение PS1
каждый раз, когда выводится приглашение.
set_bash_prompt(){
PS1="\[email protected]\h $(call_your_function) $>"
}
PROMPT_COMMAND=set_bash_prompt
Таким образом, PS1 будет интерпретироваться каждый раз, когда будет отображаться приглашение, поэтому он будет вызывать функцию и правильно отображать все экранирующие последовательности, включая \[ \]
, которые важны для подсчета длины запроса (например, для правильной работы команды).
Надеюсь, это поможет кому-то, поскольку я потрачу полдня на решение этой проблемы.
Ответ 2
Используйте \001
вместо \[
и \002
вместо \]
и помните о последствиях использования PROMPT_COMMAND
как этот метод будет сбрасывать приглашение каждый раз (что также может быть именно тем, что вам нужно).
Решение для bash, отображающего цвета внутри функции, объясняется здесь:
\[
\]
Являются особыми, только когда вы назначаете PS1, если вы печатаете их внутри функции, которая запускается, когда отображается подсказка, она не работает. В этом случае вам нужно использовать байты \001
и \002
Есть также этот другой ответ, который указывает в том же направлении:
специфичные для bash \[
и \]
фактически переводятся в \001
и \002
Установка PS1
внутри функции, вызываемой PROMPT_COMMAND
, как предложено в принятой aswer сбрасывает PS1
каждый раз, не позволяя другие скрипты легко модифицировать promtp (например Python virtualnenv activate.sh):
$ echo $PS1
<your PS1>
$ PS1="(TEST)$PS1"
$ echo $PS1
<(TEST) is not prepended to PS1 if you are using PROMPT_COMMAND as it is reset>
Ответ 3
\[
и \]
должны использоваться непосредственно в $PS*
, а не просто выводить их через echo
.
LIGHTGREEN="\033[1;32m"
LIGHTRED="\033[1;31m"
WHITE="\033[0;37m"
RESET="\033[0;00m"
function error_test {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
PS1="\u\[\$(error_test)\]@\w\[$RESET\] \$ "
Ответ 4
Здесь цветная строка кода выхода my PS1
code:
color_enabled() {
local -i colors=$(tput colors 2>/dev/null)
[[ $? -eq 0 ]] && [[ $colors -gt 2 ]]
}
BOLD_FORMAT="${BOLD_FORMAT-$(color_enabled && tput bold)}"
ERROR_FORMAT="${ERROR_FORMAT-$(color_enabled && tput setaf 1)}"
RESET_FORMAT="${RESET_FORMAT-$(color_enabled && tput sgr0)}"
# Exit code
PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $BOLD_FORMAT $ERROR_FORMAT $exit_code $RESET_FORMAT " ")'
Снимок экрана (с одним анонимным коннектором репозитория Subversion):
![Color coded output]()
Ответ 5
Я понимаю, что это старая тема, но я просто получил эту работу с функциями. Трюк состоит в том, чтобы разделить печатные и непечатные части функции вверх, чтобы вы могли правильно скопировать непечатаемые части с помощью []. Обычно мне нравится моя строка ERROR.., чтобы быть отдельной (и это не проблема), но это также работает правильно, если все все в одной строке.
Обратите внимание, что я возвращаю предыдущий $? значение из каждой подколонки так $? распространяется от одного к другому.
PS1="\n\
\[\`
cja_prv_retval=\$?;
if [ \$cja_prv_retval != 0 ];
then echo -ne \$E_ERROR;
fi
exit \$cja_prv_retval
\`\]\
\`
cja_prv_retval=\$?;
if [ \$cja_prv_retval != 0 ];
then echo -ne \"ERROR: RETURN CODE \$cja_prv_retval\";
fi
exit \$cja_prv_retval
\`\
\[\`
cja_prv_retval=\$?;
if [ \$cja_prv_retval != 0 ];
then echo -ne \$E_RESET;
fi
exit \$cja_prv_retval
\`\]\
${P_RESET}${P_GRAY}\! \t ${P_RED}\u${P_GRAY}@${P_GREEN}\h ${P_YELLOW}\w ${P_CYAN} ══>${P_RESET} "
Это дает мне либо
2021 12:28:05 [email protected] ~ ══>
если нет ошибки, или
ERROR: RETURN CODE 1 2021 12:28:16 [email protected] ~ ══>
если есть ошибка. Все правильно размещено (многострочное редактирование истории работает правильно).
Ответ 6
Это будет нормально работать.
LIGHTGREEN="\e[32m"
LIGHTRED="\e[31m"
RESET="\e[0m"
error_test () {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
export PS1=$(printf "$(error_test) $(whoami)@${RESET}$(pwd) ")
Ответ 7
Вот реализация, которая работает на терминале MacOS для установки PS1 с окраской, а что нет.
Существует две реализации, одна из которых полагается на echo, а другая - на printf для динамического вызова методов, не нарушая ад.
Это только начало, но надежное и не будет мерцать терминал. Поддерживает git branch прямо сейчас, но может быть расширен в конечном итоге.
Можно найти здесь:
https://github.com/momomo/opensource/blob/master/momomo.com.shell.style.sh
Должен работать просто скопировать и вставить. Нет зависимостей.