подсказка bash и повторяющиеся цвета внутри функции - PullRequest
43 голосов
/ 06 июля 2011

У меня есть это в моем .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\[\]@~/

Выход [и] вокругЦветовые коды отображаются в моей подсказке.Если я удаляю управляющие коды из-за цветов, это работает, но тогда перенос строки bash терпит неудачу.

Обратите внимание, что если PS1="LIGHTGREEN - whatever - $RESET" работает, и [и] не экранированы.Тем не менее, я хочу сделать это внутри функции, которая кажется проблемой.

Я не могу найти хорошую документацию по этому вопросу.man echo даже не указывает опцию -e.Похоже, что у Bash много недокументированных, рукописных знаний.

Ответы [ 6 ]

49 голосов
/ 22 декабря 2012

Я нашел эту тему в поиске ответа, как установить цвет bash с экранированием \[ \] из функции bash.

На самом деле решение есть.Bash позволяет генерировать подсказку PS1 каждый раз, когда подсказка отображается.

set_bash_prompt(){
    PS1="\u@\h $(call_your_function) $>"
}

PROMPT_COMMAND=set_bash_prompt

Таким образом, PS1 будет интерпретироваться при каждом отображении подсказки, поэтому он будет вызывать функцию и правильно отображать все экранирующие последовательности, включая \[ \], которые важны для подсчета длины подсказки (например, дляистория команд работает правильно).

Надеюсь, это кому-нибудь поможет, так как я трачу полдня на решение этой проблемы.

23 голосов
/ 18 апреля 2017

Используйте \001 вместо \[ и \002 вместо \] и помните о последствиях использования PROMPT_COMMAND, так как этот метод будет сбрасывать приглашение каждый раз (что также может быть хочешь).

Объяснение решения для эхо-сигналов bash-подсказки внутри функции объяснено здесь :

\[ \] являются специальными только при назначении PS1, если вы их печатаете внутри функции, которая запускается, когда отображается подсказка, она не Работа. В этом случае вам нужно использовать байты \001 и \002

Существует также этот другой ответ , который указывает в том же направлении:

bash-специфичные \[ и \] фактически переводятся в \001 и \002

Установка PS1 внутри функции, вызываемой PROMPT_COMMAND, как предложено в принятом aswer, сбрасывает PS1 каждый раз, не позволяя другим сценариям легко изменять ваш запрос (например, Python virtualnenv activ.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>
7 голосов
/ 06 июля 2011

\[ и \] должны использоваться непосредственно в $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\] \$ "
0 голосов
/ 30 ноября 2017

Это будет хорошо работать.

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) ")
0 голосов
/ 18 мая 2012

Я понимаю, что это старая тема, но я только что начал работать с функциями.Хитрость заключается в том, чтобы разделить печатную и непечатаемую части функции так, чтобы вы могли правильно заключить непечатаемые части в [].Обычно мне нравится, когда моя строка 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 cja@morpheus04 ~ ══>

, если нет ошибки, либо

ERROR: RETURN CODE 1 2021 12:28:16 cja@morpheus04 ~ ══>

, если естьошибка.Все правильно расположено (редактирование многострочной истории работает правильно).

0 голосов
/ 06 июля 2011

Вот цветная часть кода выхода мой PS1 код :

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...