Pourquoi ma fonction n'est-elle pas réévaluée dans PS1?

15

J'essaie d'avoir une partie de mon invite définie dynamiquement par une fonction, donc dans mon .bashrcj'ai:

asdf ()
{
    echo -n $(pwd)
}
PS1="\u@\h:\w $(asdf)\$ "

Ouvrir un shell me donne ce que j'attends au début:

$ bash
darthbith@server:~/test /home/darthbith/test$

Cependant, lorsque je change de répertoire, la partie définie par la fonction ne change pas:

darthbith@server:~/test /home/darthbith/test$ cd ~/test2
darthbith@server:~/test2 /home/darthbith/test$

Mon objectif réel est d'utiliser le git-prompt.shscript pour afficher la branche de mon référentiel git lorsque je suis dans une seule avec de jolies couleurs et tout, mais le problème est qu'il ne met jamais à jour le nom de la branche lorsque je change de référentiel. L'exemple trivial ci-dessus est la reproduction la plus simple que j'ai pu trouver pour ma question.

Les .bashrclignes que j'ai pour intégrer le script git-prompt:

source ~/.git-prompt.sh
PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1)\$ "
Darkbith
la source
Sur une note latérale, si vous voulez une invite git, je recommanderais github.com/magicmonty/bash-git-prompt/blob/master/README.md
mgor

Réponses:

22

Selon le guide d'invite Bash :

[21:58:33][giles@nikola:~]$ PS1="[\$(date +%H%M)][\u@\h:\w]\$ "
[2159][giles@nikola:~]$ ls
bin   mail
[2200][giles@nikola:~]$

Il est important de noter la barre oblique inverse avant le signe dollar de la substitution de commande. Sans cela, la commande externe est exécutée exactement une fois: lorsque la chaîne PS1 est lue dans l'environnement.

mgor
la source
Je vous remercie! Maintenant, si seulement je pouvais le faire imprimer les couleurs au lieu des séquences d'échappement renvoyées par la fonction ...
darthbith
6

Lorsque vous l'utilisiez $(..)entre guillemets, le shell évaluait la substitution de commande avant de l'attribuer PS1. Ainsi, PS1ne contenait que la sortie, pas la substitution de commande elle-même. Au lieu de cela, utilisez des guillemets simples ou échappez à $, de sorte que la chaîne soit transmise telle quelle PS1, puis évaluée lorsque l'invite est définie:

$ PS1='$(pwd) $ '
/tmp $ cd /var
/var $ echo "$PS1"
$(pwd) $ 

Comparer:

/var $ PS1="$(pwd) $ "
/var $ echo "$PS1"
a /var $  a
/var $ 
muru
la source