Bash qui ne clobera pas les longues commands

J'essaie de configurer une invite bash pour - hostname(screen#):directory$ qui est coloré en vert si la dernière command s'est terminée avec succès, en rouge sinon. C'est ce que j'ai jusqu'à présent, qui fait effectivement le travail mais semble causer des problèmes d'affichage si la command enveloppe une ligne:

  PS1="\[\`if [[ \$? = "0" ]]; then echo '\e[32m'; else echo '\e[31m' ; fi\` - \h(${WINDOW}):\W$\e[00m " 

Googling the issue J'ai trouvé ce post SO utile avec un commentaire qui mentionne l'emballage des caractères non imprimables dans \\[ et \\] pour éviter ce problème. Par conséquent, j'ai essayé ce qui suit, mais cela n'a pas résolu le problème, et brise en outre le changement de couleur:

 PS1="\[\`if [[ \$? = "0" ]]; then echo '\e[32m'; else echo '\e[31m' ; fi\`\] - \h(${WINDOW}):\W$\[\e[00m\] " 

Comment puis-je conserver la structure de cette invite, avec des colors, mais la corriger pour que les longues commands soient affichées correctement?

J'ai une invite de fantaisie avec des colors, et maintenant bash ne semble pas savoir à quel point mon terminal est large. Les lignes s'enroulent incorrectement.


J'ai une autre façon de le faire, mettez ce code dans votre ~/.bashrc ou créez un nouveau file et source file :

 PROMPT_COMMAND=$( cat<<-'EOF' retval=$? RED=$(tput setaf 1) GREEN=$(tput setaf 2) STOP=$(tput sgr0) # arithmetic using bash parameter expansion on a array if (($retval + ${PIPESTATUS[@]/%/+} + 0)); then PS1="\[$RED\]\u@\h:\w$ \[$STOP\]" else PS1="\[$GREEN\]\u@\h:\w$ \[$STOP\]" fi EOF ) 

Cela fera l'affaire =)

Bash exécutera le code à l'intérieur de PROMPT_COMMAND pour chaque command.

Si vous avez un problème de copyr / coller, vous pouvez download le script

tput

EXPLICATIONS

  • (( )) est arithmétique dans bash , voir http://wiki.bash-hackers.org/syntax/arith_expr
  • PROMPT_COMMAND : si elle est définie, la valeur est exécutée en tant que command avant d'émettre chaque invite principale. Voir man bash | less +/PROMPT_COMMAND man bash | less +/PROMPT_COMMAND
  • tput est meilleur que les codes d'échappement ANSI tput dur. Voir http://wiki.bash-hackers.org/scripting/terminalcodes
  • PIPESTATUS : Variable de tableau contenant une list des valeurs d'état de sortie des process du pipeline de premier plan le plus récemment exécuté (qui ne peut contenir qu'une seule command). Voir man bash | less +/PIPESTATUS man bash | less +/PIPESTATUS
  • cat<<-'EOF' est un doc ici spécial: le - caractère signifie que je peux indenter le code, et les guillemets simples sur 'EOF' signifie ne pas interpoler les variables

J'ai une invite de 2 lignes, donc les choses potentiellement longues n'affecteront pas la command line:

 glennj@homebase ~/tmp 2219 $ set | grep PS1= PS1='\n\u@\h \w\n\! \$ ' 

Pas \\[ , juste \[ . Vous avez aussi un \[ au début.

Ce n'est pas une réponse directe à la question initiale, c'est juste un exemple d'utilisation.

Basé et merci à la réponse de @ stArdustͲ, j'ai trouvé une solution appropriée pour une invite de command personnalisée pour afficher l'état de la batterie * , dans le coin supérieur droit du terminal. Les colors sont définies dans un file indépendant qui provient de .bashrc .

 PROMPT_COMMAND=$( cat<<-'EOF' function battery_percentage { PERCENTAGE=$(upower -i $(echo $(upower -e |grep 'battery')) |grep 'percentage' |sed -e 's/^[ \t]*//;s/[[:space:]]\+/ /g;s/[ \t]*$//' |cut -d' ' -f2 |cut -d"%" -f1) BColor='IGray' if [ "${PERCENTAGE}" -lt 15 ] then PColor='BlinkIRed' PBackground='On_White' else PColor='Gray' fi echo "\001${!BColor}\002Battery\001${!PColor}\002 ${PERCENTAGE}% \001${Reset}\002" } function battery_time { TIME=$(upower -i $(echo $(upower -e |grep 'battery')) |grep 'time' |sed -e 's/^[ \t]*//;s/[[:space:]]\+/ /g;s/[ \t]*$//' |cut -d' ' -f4,5) echo "\001${IGray}\002${TIME}\001${Reset}\002" } export PS1="\[\e[s\]\[\e[1;\$((COLUMNS-26))f\]$(battery_percentage) $(battery_time)\[\e[u\]${PS1}" EOF ) 

Enfin, la PS1 ressemble à:

 \[\e[s\]\[\e[1;$((COLUMNS-26))f\]\001\e[0;38;5;8m\002Battery\001\e[0;38;5;7m\002 82% \001\e[0m\002 \001\e[0;38;5;8m\0023.6 hours\001\e[0m\002\[\e[u\]\[\e[0;38;5;232m\]\[\e[48;5;5m\] \u \[\e[0;38;5;5m\]\[\e[48;5;11m\] \[\e[0;38;5;232m\]\[\e[48;5;11m\]@\H \[\e[0;38;5;11m\]\[\e[48;5;0m\]\[\e[0m\] \[\e[0;38;5;6m\]\w\a \[\e[1;38;5;5m\]→\e[0m 

Notez que j'ai quelques problèmes de positionnement du slider quand je fais défiler l'historique des commands.


* d'un ordinateur portable ThinkPad