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

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.

4b9b3361

Ответ 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

Должен работать просто скопировать и вставить. Нет зависимостей.