Каково различие между PS1 и PROMPT_COMMAND

При взгляде на этот потрясающий поток я заметил, что некоторые примеры используют

PS1="Blah Blah Blah"

и некоторое использование

PROMPT_COMMAND="Blah Blah Blah"

(и некоторое использование оба) при установке подсказки в оболочке удара. Каково различие между двумя? ТАК поиск и даже немного более широкого поиска Google не получает меня результаты, поэтому даже ссылка на правильное место для поиска ответа ценилась бы.

105
задан whtyger 4 September 2019 в 14:34
поделиться

2 ответа

Со страницы документации GNU Bash: 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.

57
ответ дан 24 November 2019 в 04:00
поделиться

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 $ 

Update

После прочтения комментариев и ответа Боба я думаю, что писать так, как он описывает, лучше. Он более удобен для обслуживания, чем то, что я написал выше, где переменная 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
67
ответ дан 24 November 2019 в 04:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: