Взглянув на эту удивительную тему, я заметил, что некоторые примеры используют
PS1="Blah Blah Blah"
и некоторые используют
PROMPT_COMMAND="Blah Blah Blah"
(и некоторые используют оба) при установке приглашения в оболочке bash. Какая разница между двумя? Поиск SO и даже немного более широкий поиск в Google не дают мне результатов, поэтому даже ссылка на нужное место, где можно найти ответ, была бы признательна.
Ответ 1
На странице GNU Bash doc: http://www.gnu.org/software/bash/manual/bashref.html
PROMPT_COMMAND
If set, the value is interpreted as a command to execute before
the printing of each primary prompt ($PS1).
Я никогда не использовал его, но я мог бы использовать это обратно, когда у меня был только sh.
Ответ 2
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 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
Ответ 3
Разница заключается в том, что PS1 - это фактическая строка приглашения, а PROMPT_COMMAND - это команда, которая выполняется непосредственно перед приглашением. Если вам нужен самый простой и гибкий способ создания подсказки, попробуйте следующее:
Поместите это в свой .bashrc:
function prompt_command {
export PS1=$(~/bin/bash_prompt)
}
export PROMPT_COMMAND=prompt_command
Затем напишите script (bash, perl, ruby: ваш выбор) и поместите его в ~/bin/bash_prompt.
script может использовать любую информацию, которая ему нравится, для создания подсказки. Это намного проще ИМО, потому что вам не нужно изучать несколько барочный язык замещения, который был разработан только для переменной PS1.
Вы можете подумать, что можете сделать то же самое, просто установив PROMPT_COMMAND прямо в ~/bin/bash_prompt и установив PS1 в пустую строку. Сначала это работает, но вскоре вы обнаружите, что код readline ожидает, что PS1 будет настроен на фактическое приглашение, а когда вы прокрутите назад истории в истории, в результате все будет запутано. Это обходное решение заставляет PS1 всегда отображать последнюю подсказку (так как функция устанавливает фактический PS1, используемый вызывающим экземпляром оболочки), и это делает работу readline и истории команд прекрасной.
Ответ 4
С man bash
:
PROMPT_COMMAND
Если установлено, значение выполняется как команда перед отправкой каждого основного запроса.
PS1
Значение этого параметра раскрывается (см. пРЕДУПРЕЖДЕНИЕ ниже) и используется в качестве основной строки приглашения. Значением по умолчанию является ''\s-\v\$ ''.
Если вы просто хотите установить строку приглашения, достаточно использовать только один PS1
:
PS1='user \u on host \h$ '
Если вы хотите сделать что-то еще непосредственно перед печатью приглашения, используйте PROMPT_COMMAND
. Например, если вы хотите синхронизировать кэшированные записи на диск, вы можете написать:
PROMPT_COMMAND='sync'
Ответ 5
разница в том, что
- если вы
PROMPT_COMMAND
неполную строку из PROMPT_COMMAND
, она PROMPT_COMMAND
вашу подсказку bash -
PS1
заменяет \H
и друзей -
PROMPT_COMMAND
запускает свое содержимое, PS1
использует его содержимое как подсказку.
PS1
выполняет переменное расширение и подстановку команд в каждом приглашении, нет необходимости использовать PROMPT_COMMAND
для назначения значения PS1
или для запуска произвольного кода. вы можете легко export PS1='$(uuidgen) $RANDOM'
один раз в .bash_profile
, просто использовать одинарные кавычки
Ответ 6
Да, так, чтобы попытаться действительно прибить это:
-
PROMPT_COMMAND
- это удобная переменная/функция удобства bash, но, строго говоря, нет ничего, что нельзя сделать, используя только PS1
, верно?
Я имею в виду, если кто-то хочет установить другую переменную с областью видимости вне приглашения: в зависимости от оболочки, эту переменную, вероятно, нужно будет сначала объявить за пределами $PS1
или (в худшем случае), возможно, придется привыкнуть к чему-то, ожидающему FIFO до вызова $PS1
(и снова в состоянии $PS1
в конце $PS1
); \u
\h
может вызвать некоторые проблемы, особенно если вы используете какое-то необычное регулярное выражение; но в противном случае: можно выполнить все, что может PROMPT_COMMAND
, используя подстановку команд в $PS1
(и, возможно, в угловых случаях, явные подоболочки)?
Правильно?