Bash $ PROMPT_COMMAND gâcher l'affichage de l'historique des défilement

J'ai mis en place un PROMPT_COMMAND pour afficher la twig courante pendant que je suis dans un repo git.

La partie pertinente de mon .bashrc est:

 export PS1=" \[\033[34m\]\$\[\033[0m\] " export PROMPT_COMMAND="$HOME/bin/myprompt" 

où ~ / bin / myprompt est:

 #!/usr/bin/env ruby green = "\033[32m" bold = "\033[1m" underline = "\033[4m" reset = "\033[0m" home_regex = Regexp.new "^#{ENV["HOME"]}" Dir.chdir ENV["PWD"] out = underline + bold + green + `pwd`.gsub(home_regex, "~").chomp + reset if `git log 2>&1 | grep ^fatal`.chomp == "" out += "#{underline}#{green} (#{`git branch | grep ^\* | sed s/^..//g`.chomp})#{reset}" end print out 

Cela fonctionne très bien, le seul problème est que lorsque j'utilise les touches fléchées pour faire défiler l'historique des commands, la command est parfois écrite sur mon message. Supposons la session suivante:

 ~ $ pwd /Users/Adrian ~ $ cd sibilant ~/sibilant (master) $ pwd /Users/Adrian/sibilant ~/sibilant (master) $ 

Ensuite, j'appuie sur la flèche vers le haut pour faire défiler l'historique des commands. chaque ligne montre le résultat d'une pression de la flèche:

 ~/sibilant (master) $ pwd ~/sibilant (master) $ cd sibilant ~/spwd 

comme vous pouvez le voir, la dernière fois que j'ai appuyé sur la flèche, la command a été écrite sur mon message.

Quelqu'un at-il vécu cela et / ou savoir comment y remédier?

Au lieu de le mettre dans PROMPT_COMMAND , mettez-le dans PS1 :

 PS1='$($HOME/bin/myprompt) \[\033[34m\]\$\[\033[0m\] ' 

Quand il est dans PS1 , bash count le nombre de caractères qui sont imprimés afin qu'il puisse redessiner correctement lorsque vous faites défiler votre historique. C'est pourquoi bash a les caractères spéciaux \[ et \] – ils disent à bash que les caractères ci-joints ne sont pas imprimables, ce qui aide bash à comprendre comment redessiner l'invite si nécessaire.

Notez que la substitution de command est à l'intérieur des guillemets simples. Cela empêche l'expansion au moment de l'affectation. Si la substitution de command était entre guillemets ou sans guillemets, la sortie de myprompt serait capturée une fois au moment de l'affectation et restrait statique. Afin de prendre en charge les valeurs variables qui changent au fil du time, l'interpréteur de commands étend la valeur de PS1 chaque fois que l'invite est affichée. Cela signifie que l'expansion doit être évitée au moment de l'atsortingbution en citant. Cela signifie également que vous devez faire attention à la vitesse: si la substitution de la command dure une seconde, alors votre invite prendra 1 seconde pour s'afficher.

PROMPT_COMMAND peut contenir une command qui est exécutée avant que la nouvelle invite ne soit imprimée par bash (donc avant l'évaluation de PS1).

Avec git 1.8.1, le code pour le faire efficacement avec PROMPT_COMMAND a été libéré. Voir l' utilisation de git-prompt.sh avec PROMPT_COMMAND . Le code peut fonctionner avec les versions antérieures de git, il suffit de copyr le file consortingb / completion / git-prompt.sh à un endroit où vous pouvez le find à partir de votre file .bashrc.

À votre santé

Simon