Почему вызов функции из PS1 требует экранирования? - PullRequest
3 голосов
/ 22 января 2020

Я настраиваю свое приглашение внутри .bash_profile следующим образом

export PS1="\w\$(getBranchName)\n ---->"

Моя getBranchName функция существует, и это работает, хорошо.

Мой вопрос, почему Мне нужно избежать вызова на getBranchName, как это \$(getBranchName).

Другими словами, почему этот код не работает, вместо этого?

export PS1="\w$(getBranchName)\n ---->"

Если любопытно Так выглядит функция getBranchName

esc="\033"
redf="${esc}[31m"
green="${esc}[32m"
purple="${esc}[35m"
cyanf="${esc}[36m"
reset="${esc}[0m"

getBranchName() {
  if [[ "$(__git_ps1 '%s')" == "master" ]]
  then
    echo -e "${redf}$(__git_ps1)${reset}";
  else
    echo -e "${cyanf}$(__git_ps1)${reset}";
  fi
}

export PS1="\w\$(getBranchName)\n ---->"

Ответы [ 3 ]

6 голосов
/ 22 января 2020

Вам нужно избежать доллара, потому что вы хотите сохранить этот точный текст в вашей переменной.

Попробуйте набрать echo "$PS1". Вы должны увидеть точный текст: \w$(getBranchName)\n ---->

Если вы не избежите этого, функция будет оценена только один раз, во время выделения.


Суть в том, что PS1 - это специальная переменная: каждый раз, когда вы выводите на экран новую строку, переменная оценивается для извлечения настроек дисплея.

3 голосов
/ 22 января 2020

Переменная PS1 в основном представляет собой строку шаблона (которая может содержать вызовы функций), которая оценивается каждый раз, когда отображается приглашение.

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

Если бы вы встраивали вызов функции непосредственно в строку, функция была бы вызвана один раз сразу (т. е., вероятно, при входе в систему), и ваш PS1 будет содержать результат этого единственного вызова функции, оцененный во время вашего первоначального входа в систему. Таким образом, значение больше не будет обновляться, так как функция больше не вызывается (так как PS1 больше не содержит вызов функции, а только результат stati c одного).

2 голосов
/ 22 января 2020

Он экранирован, потому что вы хотите, чтобы он запускался, когда оболочка оценивает $PS1 при каждом его отображении, а не только во время назначения.

Другие расширения (которые должны использовать tput, если вам не нравится случайные управляющие коды на всех не-ANSI терминалах), которые вы хотите расширить только один раз, когда вы назначаете PS1.

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