Tonin a signalé un bug dans mon invite par défaut . Exemple minimal:
Définir PS1:
PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " ")$ '
À ce stade, l'invite ressemble à ceci:
$
Maintenant, triggers la sortie du code de sortie en exécutant:
false
Maintenant, l'invite contient le code de sortie en rouge au début de la ligne:
1 $
Tapez "false". Maintenant, l'invite contient uniquement la search:
(reverse-i-search)`false': false
L'historique du terminal résultant contient maintenant les éléments suivants:
1 $ch)`false': false
Production attendue:
1 $ false
Autrement dit, il semble que la sortie de search d'historique soit mélangée à l'invite et cache la command réelle exécutée.
J'ai essayé de contourner cela en utilisant PROMPT_COMMAND
:
set_exit_code() { exit_code=$? [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " " } set_bash_prompt() { PS1='$(set_exit_code)$ ' # Double quotes give the same result } PROMPT_COMMAND=set_bash_prompt
Cela ne semble pas fonctionner – la ligne est exactement la même qu'avant la search et l'exécution.
Comment puis-je réparer cela?
J'ai trouvé la réponse sur askubuntu.com . @qeirha a mentionné que vous devez dire à bash que la séquence des caractères ne doit pas être comptée dans la longueur de l'invite, et vous faites cela en l'enfermant dans \[
\]
. Basé sur l'exemple fourni, voici une solution:
red=$(tput setaf 1) reset=$(tput sgr0) [ "$PS1" = "\\s-\\v\\\$ " ] && PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$red\] $exit_code \[$reset\] " ")$ '
PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " ")$ '
(Désolé, aucune explication ici.) Voir comment personnaliser PS1 correctement ou toute autre question sur les problèmes de calcul de la longueur d'invite et \[
.. \]
.)
En développant la réponse @manatwork mais en gardant votre code fractionnant le calcul PS1
dans différentes fonctions, vous pouvez écrire votre message de la manière suivante:
set_exit_code() { exit_code=$? [[ $exit_code -eq 0 ]] || printf "\[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " } set_bash_prompt() { PS1="$(set_exit_code)$ " # with double quotes! } PROMPT_COMMAND=set_bash_prompt
Les guillemets sont obligatoires à la fois lors de la définition de PS1
et lors de l'utilisation de printf
dans la fonction.