PROMPT_COMMAND может содержать обычные операторы bash, тогда как переменная PS1 может также содержать в переменной специальные символы, такие как '\ h' для имени хоста.
Например, вот мое приглашение bash, в котором используются как PROMPT_COMMAND, так и PS1. Код bash в PROMPT_COMMAND определяет, в какой ветке git вы можете быть, и отображает это в приглашении вместе со статусом выхода последнего запущенного процесса, именем хоста и базовым именем pwd. Переменная RET хранит возвращаемое значение последней выполненной программы. Это удобно, чтобы увидеть, была ли ошибка, и код ошибки последней программы, которую я запускал в терминале. Обратите внимание на внешнее окружение всего выражения PROMPT_COMMAND. Он включает PS1, поэтому эта переменная повторно оценивается каждый раз, когда оценивается переменная PROMPT_COMMAND.
PROMPT_COMMAND='RET=$?;\
BRANCH="";\
ERRMSG="";\
if [[ $RET != 0 ]]; then\
ERRMSG=" $RET";\
fi;\
if git branch &>/dev/null; then\
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2);\
fi;
PS1="$GREEN\u@\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'
Пример вывода в каталоге, отличном от git, выглядит так:
sashan@dhcp-au-122 Documents $ false
sashan@dhcp-au-122 Documents 1 $
а в каталоге git вы видите имя ветки:
sashan@dhcp-au-122 rework mybranch $
Обновить
После прочтения комментариев и ответа Боба я думаю, что лучше писать так, как он описывает. Он более удобен в обслуживании, чем то, что я изначально написал выше, где переменная PS1 устанавливается внутри PROMPT_COMMAND, которая сама по себе является сверхсложной строкой, которая оценивается во время выполнения с помощью bash. Это работает, но это сложнее, чем должно быть. Честно говоря, я написал эту PROMPT_COMMAND для себя около 10 лет назад, и она сработала, и я не особо об этом задумывался.
Для тех, кому интересно, как я изменил свои вещи, я в основном поместил код для PROMPT_COMMAND в отдельный файл (как описал Боб), а затем повторил строку, которую я собираюсь использовать как PS1:
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour
if [ -z $SCHROOT_CHROOT_NAME ]; then
SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=$1
if [[ $RET != 0 ]]; then
ERRMSG=" $RET"
fi
if which git &>/dev/null; then
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2)
else
BRANCH="(git not installed)"
fi
echo "${GREEN}\u@\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"
и в моем .bashrc
function prompt_command {
RET=$?
export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
if git branch &>/dev/null ; then\
. Он перенаправляет как stdout, так и stderr в / dev / null. tldp.org/LDP/abs/html/io-redirection.htmlPROMPT_COMMAND
.Don't set PS1 in PROMPT_COMMAND! Set variables in PROMPT_COMMAND and use them in PS1
PS1
онлайн внутриPROMPT_COMMAND
невыгодно. Совершенно полезный код. В отличие от ответа Боба,PS1
переменная была построена правильно. Это позволяет использовать гораздо более сложные приглашения bash в зависимости от вашей реальной ситуации.PS1
внутриPROMPT_COMMAND
не имеет смысла. это пример того, как этого не делать. построитьPS1
один раз.bash_profile
, просто используйте одинарные кавычки вместо двойных, чтобы подстановки переменных оценивались во время каждого запроса.Разница в том, что PS1 - это фактическая используемая строка приглашения, а PROMPT_COMMAND - это команда, которая выполняется непосредственно перед приглашением. Если вам нужен самый простой и гибкий способ создания подсказки, попробуйте следующее:
Поместите это в свой .bashrc:
Затем напишите сценарий (bash, perl, ruby: на ваш выбор) и поместите его в ~ / bin / bash_prompt.
Сценарий может использовать любую информацию для создания приглашения. Это намного проще IMO, потому что вам не нужно изучать несколько причудливый язык подстановки, который был разработан только для переменной PS1.
Вы можете подумать, что можете сделать то же самое, просто установив PROMPT_COMMAND непосредственно на ~ / bin / bash_prompt и установив PS1 на пустую строку. Поначалу кажется, что это работает, но вскоре вы обнаружите, что код строки чтения ожидает, что PS1 будет установлен на фактическую подсказку, и когда вы прокручиваете обратные слова в истории, все в результате запутывается. Этот обходной путь приводит к тому, что PS1 всегда отражает последнее приглашение (поскольку функция устанавливает фактический PS1, используемый вызывающим экземпляром оболочки), и это позволяет нормально работать со строкой чтения и историей команд.
источник
PS1
вPROMPT_COMMAND
! Установите переменныеPROMPT_COMMAND
и используйте их вPS1
. В противном случае вы потеряете возможность использоватьPS1
escape-последовательности, такие как\u
или\h
. Вы должны изобрести их зановоPROMPT_COMMAND
. Это могло бы быть возможно, но невозможно обойти потерю\[
и\]
которые отмечают начало и конец непечатаемых символов. Это означает, что вы не можете использовать цвета, не запутывая терминал длиной приглашения. И это сбивает с толкуreadline
при редактировании команды, порождающей две строки. В итоге на экране большой беспорядок.PROMPT_COMMAND
выполняется перед печатьюPS1
. Я не вижу проблем с настройкойPS1
изнутриPROMPT_COMMAND
, потому что послеPROMPT_COMMAND
завершения будет печататься оболочкаPS1
, которая была изменена изPROMPT_COMMAND
(или, в данном случае, внутриprompt_command
)?export PS1='$(~/bin/bash_prompt)'
делает то же самое, ошибка выглядит нормальноОткуда
man bash
:Если вы просто хотите установить строку приглашения, используя
PS1
одного:Если вы хотите сделать что-то еще перед печатью приглашения, используйте
PROMPT_COMMAND
. Например, если вы хотите синхронизировать кэшированные записи на диск, вы можете написать:источник
PS1
без необходимостиPROMPT_COMMAND
, поскольку последовательность, которая устанавливает заголовок, может быть включена вPS1
оболочку с помощью\[
и\]
.PS1
, она просто будет установлена в подоболочке, поэтому вы не сможете вернуть ее значение. но твой пример баналенPS1='$(sync)user \u on host \h$ '
разница в том, что
PROMPT_COMMAND
, она испортит ваше приглашение bashPS1
заменители\H
и друзьяPROMPT_COMMAND
запускает его содержимое,PS1
использует его как подсказку.PS1
выполняет расширение переменных и подстановку команд в каждом запросе, нет необходимости использоватьPROMPT_COMMAND
для присвоения значенияPS1
или для запуска произвольного кода. вы можете легко сделатьexport PS1='$(uuidgen) $RANDOM'
один раз.bash_profile
, просто используйте одинарные кавычкиисточник
Да, так что, чтобы попытаться по-настоящему закрепить это:
PROMPT_COMMAND
- это удобная переменная / функция bash , но, строго говоря, нет ничего, что нельзя было бы сделать, используя вPS1
одиночку, правильно?Я имею в виду, если кто-то хочет установить другую переменную с областью действия за пределами подсказки: в зависимости от оболочки, эту переменную, вероятно, нужно будет объявить сначала снаружи
$PS1
или (в худшем случае), возможно, придется пофантазировать с чем-то, ожидающим в FIFO до звонит$PS1
(и снова вооружается в конце$PS1
);\u
\h
может вызвать некоторые проблемы, особенно если вы используете некоторые фантазии регулярные выражения; но в остальном: можно добиться всегоPROMPT_COMMAND
, используя подстановку команд внутри$PS1
(и, может быть, в крайних случаях, явные подоболочки)?Правильно?
источник