Как включить команды в PS1 Bash без расчета длины строки?

Тонин указал на ошибку в моей подсказке по умолчанию . Минимальный пример:

  1. Установите PS1:

    PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " ")$ ' 

    На этом этапе запрос выглядит так:

     $ 
  2. Теперь выведите выходной код выхода, запустив:

     false 

    Теперь приглашение содержит код выхода в красном в начале строки:

     1 $ 
  3. Нажмите Ctrl- r .
  4. Введите «false». Теперь приглашение содержит только поиск:

     (reverse-i-search)`false': false 
  5. Нажмите Enter .

Результирующая история терминала теперь содержит следующее:

 1 $ch)`false': false 

Ожидаемый результат:

 1 $ false 

То есть, кажется, что вывод поиска истории смешан с подсказкой и скрывает фактическую команду, которая была запущена.

Я попытался обойти это, используя PROMPT_COMMAND :

 set_exit_code() { exit_code=$? [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " " } set_bash_prompt() { PS1='$(set_exit_code)$ ' # Double quotes give the same result } PROMPT_COMMAND=set_bash_prompt 

Кажется, что это не сработало – строка выглядит точно так же, как и раньше, после поиска и запуска.

Как я могу это исправить?

3 Solutions collect form web for “Как включить команды в PS1 Bash без расчета длины строки?”

Я нашел ответ на askubuntu.com . @qeirha упомянул, что вы должны сказать bash, что последовательность символов не должна учитываться в строке приглашения, и вы делаете это, заключая ее в \[ \] . На основании приведенного примера, вот одно из решений:

 red=$(tput setaf 1) reset=$(tput sgr0) [ "$PS1" = "\\s-\\v\\\$ " ] && PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$red\] $exit_code \[$reset\] " ")$ ' 
 PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " ")$ ' 

(Извините, никаких объяснений здесь нет. См. « Как правильно настроить PS1» или любой другой вопрос о проблемах расчета длины запроса и \[ .. \] .)

Расширяясь в ответ @manatwork, но сохраняя свой код, разделяющий вычисления PS1 в разных функциях, вы можете написать свое приглашение следующим образом:

 set_exit_code() { exit_code=$? [[ $exit_code -eq 0 ]] || printf "\[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " } set_bash_prompt() { PS1="$(set_exit_code)$ " # with double quotes! } PROMPT_COMMAND=set_bash_prompt 

Двойные кавычки являются обязательными как при настройке PS1 и при использовании printf в функции.

  • Вызов Bash: использование \ в PROMPT_COMMAND
  • Использование echo -e в PS1 вызывает проблемы с разрывом строки в shell
  • Backspace удаляет приглашение Bash
  • Как я могу избежать восклицательного знака в переменной среды PS1?
  • Bash: условная новая строка в PS1 ломает typeahead
  • Как изменить формат подсказки bash?
  • Опишите подсказку, которую я вижу, когда я впервые зашел на компьютер Linux
  • bash: подсказка получает визуально нарушен
  • Подсказка «-bash-3.2 $» против «bash-3.2 $» в SunOS 5.10
  • Как поместить «клей» CWD (и т. Д.) В часть экрана вместо того, чтобы вставлять в PS1?
  • Вывод терминала неверно
  • Linux и Unix - лучшая ОС в мире.