J'ai un problème où si je tape de très longues commandes dans bash, le terminal ne rendra pas ce que je tape correctement. Je m'attendrais à ce que si j'avais une commande comme la suivante:
username@someserver ~/somepath $ ssh -i /path/to/private/key
[email protected]
La commande doit s'afficher sur deux lignes. Au lieu de cela, il se terminera souvent et commencera à écrire par-dessus mon invite, un peu comme ceci:
[email protected] -i /path/to/private/key
Si je décide de revenir en arrière et de changer un argument, rien ne dit où le curseur apparaîtra, parfois au milieu de l'invite, mais généralement sur la ligne ci-dessus où je tape.
Un plaisir supplémentaire se produit lorsque Up à une commande précédente. J'ai essayé ceci dans gnome-terminal et terminator et sur i3 et Cinnamon. Quelqu'un a suggéré que c'était mon invite, alors voici:
\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]
Ctrll, reset
et clear
font tous ce qu'ils disent, mais quand je retape la commande ou Up les mêmes choses se produisent.
J'ai vérifié et checkwinsize
est activé dans bash. Cela se produit sur 80x24 et d'autres tailles de fenêtre.
Est-ce juste une chose avec laquelle j'apprends à vivre? Y a-t-il un morceau de magie que je devrais connaître? Je me suis contenté d'utiliser une invite très courte, mais cela ne résout pas le problème.
Les séquences non imprimables doivent être incluses entre \[
et \]
. En regardant votre PS1 elle a une séquence non fermée après \W
. Mais, la deuxième entrée est redondante et répète l'instruction précédente "1; 34" .
\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]
|_____________| |_|
| |
+--- Let this apply to this as well.
En tant que tel, cela aurait dû viser la coloration:
\[\033[1;32m\]\u:\[\033[1;34m\] \W \$\[\033[0m\]
|_____|
|
+---- Bold blue.
Garder le "original" cela devrait aussi fonctionner:
\[\033[1;32m\]\u:\[\033[1;34m\] \W\[\033[1;34m\] \$\[\033[0m\]
|_| |_|
| |
+-----------+-- Enclose in \[ \]
La raison de ce comportement est due au fait que bash
pense que l'invite est plus longue qu'elle ne l'est réellement. À titre d'exemple simple, si l'on utilise:
PS1="\033[0;34m$"
1 2345678
L'invite est censée être de 8 caractères et non 1. En tant que tel, si la fenêtre du terminal est de 20 colonnes, après avoir tapé 12 caractères, elle est censée être de 20 et se termine. Cela est également évident si l'on essaie ensuite de faire un retour arrière ou Ctrl+u. Il s'arrête à la colonne 9.
Cependant, il ne démarre pas de nouvelle ligne à moins qu'il n'y en ait une sur la dernière colonne, par conséquent la première ligne est remplacée.
Si vous continuez à taper, la ligne doit passer à la ligne suivante après 32 caractères.
Il s'agit surtout de voir que la taille de la fenêtre supposée par le terminal n'est pas la même que la taille réelle de votre fenêtre. Si vous utilisez bash, vous pouvez essayer ceci.
$ shopt checkwinsize
Si vous n'obtenez pas
checkwinsize on
Activez-le ensuite avec
$ shopt -s checkwinsize
Ensuite, essayez simplement d'exécuter une autre commande (comme ls
) ou de redimensionner la fenêtre une fois, ce qui précède fonctionne pour moi à chaque fois.
Pour les systèmes Redhat en particulier, le problème est souvent causé par une mauvaise configuration ~/.bashrc
ne pas appeler /etc/bashrc
. Normalement, bash charge ~/.bashrc
qui devrait appeler /etc/bashrc
, qui contient par défaut shopt -s checkwinsize
.
J'ai lu une fois quelque part (je ne sais plus où) qu'en utilisant \001
et \002
au lieu de \[
et \]
peut résoudre ce problème. Ça l'a fait pour moi.
Soit dit en passant, la définition de la PS1 n'a pas à être laide.
green="\001$(tput setaf 2)\002"
blue="\001$(tput setaf 4)\002"
dim="\001$(tput dim)\002"
reset="\001$(tput sgr0)\002"
PS1="$dim[\t] " # [hh:mm:ss]
PS1+="$green\u@\h" # user@Host
PS1+="$blue\w\$$reset " # workingdir$
export PS1
unset green blue dim reset
Comme mentionné dans d'autres réponses, les séquences non imprimables telles que \e[0;30m
doit être entouré de \[...\]
.
De plus (et ce que je ne vois pas encore mentionné), il semble que \r\n
doit être extérieur du \[...\]
si vous avez une invite sur plusieurs lignes. Il m'a fallu quelques essais et erreurs pour finalement comprendre cela.
Cela ressemble à un problème avec vos paramètres de variable d'environnement COLUMNS
& LINES
. Lorsque vous redimensionnez la fenêtre, elles sont généralement définies automatiquement par gnome-terminal (je crois), vous pouvez les forcer à être définies manuellement en exécutant la commande resize
.
Si je redimensionne mon gnome-terminal à 79x17, mes variables apparaissent comme suit:
$ echo $COLUMNS; echo $LINES
79
17
Je peux le forcer comme ça:
$ resize
COLUMNS=79;
LINES=17;
export COLUMNS LINES;
Pour empêcher l'encapsulage, vous pouvez également augmenter le nombre de colonnes à l'aide, par ex.
stty columns 120
Le même problème peut également être causé par l'utilisation de symboles Unicode larges (comme dans https://stackoverflow.com/a/34812608/1657819 ). Voici l'extrait de code à l'origine du problème (faites attention au $Green
et $Red
sont des chaînes de couleurs correctement échappées):
FancyX='\342\234\227'
Checkmark='\342\234\223'
# Add a bright white exit status for the last command
PS1="$White\$? "
# If it was successful, print a green check mark. Otherwise, print
# a red X.
if [[ $Last_Command == 0 ]]; then
PS1+="$Green$Checkmark "
else
PS1+="$Red$FancyX "
fi
Bash ne peut pas calculer la longueur correctement, donc le moyen le plus simple pourrait être d'échapper à 2 des trois parties de ces symboles larges.
FancyX='\[\342\234\]\227'
Checkmark='\[\342\234\]\223'
tput smam
Sur Ubuntu 19.10 dans un terminal Gnome, qui a TERM=xterm-256color
, cela émet la séquence d'échappement exacte qui rend les lignes de retour à la ligne terminales:
tput smam
Vous pouvez voir ce que cette évasion est avec:
tput smam | hd
Réinitialisation de l'état du terminal avec:
reset
semble également avoir pour effet de définir tput smam
.
La page de manuel:
man terminfo
documents smam
et son opposé rmam
:
enter_am_mode smam SA turn on automatic margins
exit_am_mode rmam RA turn off automatic margins
Notez cependant que certains terminaux n'ont pas cette capacité, par exemple à l'intérieur tmux
nous avons TERM=screen-265color
et smam
n'apparaissent pas dans la liste des capacités:
infocmp
et donc tput smam
n'imprime rien.
Je ne sais pas comment, mais QEMU a pu changer l'état de retour à la ligne de tmux alors que tput
ne l'était pas .