Изменение PS1 только в том случае, если определенной подстроки еще нет в PS1 (bash)

#git #bash

#git #bash

Вопрос:

У меня есть эта маленькая изящная штучка в моем .bashrc :

 has_gitbranch() {
  if [ -e .git ]; then
    GIT_BRANCH='$(__git_ps1 "%s")'
    [ "$GIT_BRANCH" != 'master' ] amp;amp; export PS1="$GIT_BRANCH$PS1"
  fi
}

venv_cd () {
   cd "$@" amp;amp; has_gitbranch
}
alias cd="venv_cd"
  

(Я не писал это сам и не могу вспомнить, откуда я это взял)

Проблема в том, что если я вхожу в каталог, который является репозиторием git, это происходит:

 reponamepeterbe@computername:~/directory $
  

Это нормально, но что произойдет, если я снова войду в этот каталог (например, cd . ), тогда это произойдет:

 reponamereponamepeterbe@computername:~/directory $
  

И снова:

 reponamereponamereponamepeterbe@computername:~/directory $
  

Как я могу изменить оператор bash if, чтобы он не добавлял имя ветки git, если оно уже есть в $PS1 ?

Если бы это был Python, я бы просто сделал это:

 GIT_BRANCH = get_current_git_repo_name()
if GIT_BRANCH not in PS1: # or PS1.find(GIT_BRANCH) == -1
      PS1 = GIT_BRANCH   PS1
  

Ответ №1:

 case "$PS1" in
"$GIT_BRANCH"*)
    ;;
*)
    PS1="$GIT_BRANCH$PS1"
    ;;
esac
  

Тем не менее, вы решаете неправильную проблему; я бы сохранил базовое PS1 значение где-нибудь в другом месте и всегда строил PS1 на основе этого и текущего имени репозитория. Подумайте, что произойдет, если вы cd /some/other/repo .

Комментарии:

1. В инструкции case: s/of/in/

2. Это действительно отвечает на вопрос. Но вы правы, это не решает проблему с перемещением в другой каталог. Однако, поскольку я также использую виртуальные среды Python, есть еще одна функция bash, которая выполняет другую магию с PS1, так что теперь это работает для меня идеально.

Ответ №2:

Я довольно смущен, почему вы пытаетесь изменить PS1 на лету. В этом нет необходимости. Вот мой итог:

 PS1='.....[!]$(__git_ps1 "(%s)")$ '
  

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

Для справки, вот пример, взятый из git-completion.bash :

 PS1='[u@h W$(__git_ps1 " (%s)")]$ '
  

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