web-dev-qa-db-fra.com

Comment puis-je obtenir de longues lignes de commande pour passer à la ligne suivante?

Ce qui me frustre le plus souvent depuis Ubuntu, c’est que lorsque je tape une commande sur la ligne de commande dont la largeur est supérieure à la largeur du terminal, au lieu de passer à une nouvelle ligne, elle retourne à colonne 1 sur la même ligne et commence à écraser le début de ma ligne de commande. (Cela ne remplace pas réellement la commande, mais visuellement, il écrase le texte affiché).

C'est difficile à expliquer sans le voir, mais supposons que mon terminal ait 20 caractères de largeur (le mien ressemble plus à 120 caractères - mais à titre d'exemple), et je veux faire écho à l'alphabet anglais. Ce que je tape est ceci:

echo abcdefghijklmnopqrstuvwxyz

Mais à quoi ressemble mon terminal avant d’appuyer sur la touche est:

pqrstuvwxyzghijklmno

Quand je frappe entrer, il fait écho

abcdefghijklmnopqrstuvwxyz

donc je sais que la commande a été reçue correctement. Il vient juste de terminer ma frappe après le "o" et recommence sur la même ligne.

Ce à quoi je m'attendrais, si je tapais cette commande sur un terminal de 20 caractères de large serait la suivante:

echo abcdefghijklmno
pqrstuvwxyz

Contexte: J'utilise bash comme shell et j'ai cette ligne dans mon ~/.bashrc:

set -o vi

pour pouvoir naviguer en ligne de commande avec les commandes VI. J'utilise actuellement le serveur Ubuntu 10.10 et me connecte au serveur avec PuTTY.

Dans tout autre environnement dans lequel j'ai travaillé, si je tape une longue ligne de commande, une nouvelle ligne sera ajoutée sous la ligne sur laquelle je travaille lorsque ma commande dépasse la largeur du terminal et que je continue à taper, je peux voir ma commande. 2 lignes différentes. Mais aussi longtemps que je me souvienne d’utiliser Ubuntu, mes longues commandes n’occupent qu’une ligne.

Cela se produit également lorsque je reviens aux commandes précédentes de l'historique (j'appuie sur Echap, puis sur 'K' pour revenir aux commandes précédentes). Lorsque j'arrive à une commande précédente plus longue que la largeur du terminal, la ligne de commande obtient mutilé et je ne peux pas dire où je suis dans la commande.

Le seul moyen de contourner la commande longue que j'ai trouvée consiste à appuyer sur "Esc-V", ce qui ouvre la commande actuelle dans un éditeur de VI.

Je ne pense pas avoir quelque chose d'étrange dans mon fichier .bashrc. J'ai commenté la ligne "set -o vi", et j'ai toujours eu le problème.

J'ai téléchargé une nouvelle copie de PuTTY et je n'ai apporté aucun changement à la configuration. Je viens de taper mon nom d'hôte pour me connecter, et j'ai toujours le problème, je ne pense donc pas que ce soit quelque chose avec PuTTY (sauf si je dois faire des changements de configuration)

Quelqu'un at-il eu ce problème et est-ce que quelqu'un peut penser à comment le résoudre?

Éditer

C'était mon fichier .bashrc. J'ai copié le même profil d'une machine à l'autre et j'ai utilisé des caractères spéciaux dans mon $ PS1 qui le jettent en quelque sorte. Je m'en tiens maintenant aux variables bash standard pour mon $ PS1.

Merci à @ ændrük pour le conseil sur le .bashrc!

... End Edit ...

106
BrianH

Assurez-vous que tous les octets non imprimables de votre PS1 sont contenus dans \[ \]. Sinon, bash les comptera dans la longueur de l'invite. Il utilise la longueur de l'invite pour déterminer le moment où il faut enrouler la ligne.

Par exemple, bash compte ici l’invite sur une largeur de 19 colonnes, alors que l’invite affichée par le terminal n’a qu’une largeur de 10 colonnes (My Prompt écrit en cyan et > écrit en couleur par défaut):

PS1='\e[36mMy Prompt\e[0m>'         # bash count: 19, actual: 10

alors qu'ici, l'invite n'a qu'une largeur de 10 colonnes, car il ignore les octets entre les échappements spéciaux \[ et \]:

PS1='\[\e[36m\]My Prompt\[\e[0m\]>' # bash count: 10, actual: 10

Cependant, pour une bonne pratique, utilisez tput pour générer les échappements de terminal plutôt que de les coder en dur:

cyan=$(tput setaf 6) # \e[36m
reset=$(tput sgr0)   # \e[0m
PS1='\[$cyan\]My Prompt\[$reset\]>'

Voir http://mywiki.wooledge.org/BashFAQ/05 , et aussi http://wiki.bash-hackers.org/scripting/terminalcodes pour en savoir plus sur tput .

131
geirha

Je suppose que vous avez configuré votre PS1 avec des couleurs, n'est-ce pas?

Assurez-vous simplement que \[ figure dans votre citation PS1 précédant votre jeu de couleurs.

Par exemple:

PS1='\[\e[0;32m\u@\w/:\[\e[m '
59
user10070

J'ai eu un problème similaire et j'ai finalement trouvé une solution simple.

Ajoutez la ligne suivante dans votre fichier .bashrc:

COLUMNS=250

Puis tapez source ~/.bashrc pour obtenir l’effet souhaité.

11
Deboshree

J'ai eu le même problème avec une invite de couleur personnalisée, même si je contenais des codes de couleur dans les délimiteurs \[ et \]. Il se trouve que bash a des problèmes pour faire écho aux couleurs de l'intérieur d'une fonction . J'ai fini par utiliser uniquement des variables pour mon invite, et bien que mon .bashrc soit un peu moins élégant, tout fonctionne correctement à présent.

5
reentim

Une chose simple à faire serait d’ajouter la ligne suivante avant de configurer la PS1:

stty columns 1000

Par exemple,

stty columns 1000
PS1='\[\e[0;32m\u@\w/:[\e[m '

cependant, cela affecte d'autres commandes Unix comme ls et man.

2
Gennady

\[ et \] n'ont pas fonctionné pour moi. J'imagine que la manière dont j'ai généré l'invite (à partir d'un programme externe) était différente, ou parce que mon invite était "dynamique".

Après en lisant ceci j'ai découvert que vous pouvez réellement échapper aux codes de couleur avec les octets 0x01 et 0x02.

par exemple. J'utilise une version spéciale de Chalk et j'emballe les couleurs en utilisant ceci:

const Chalk = require('@nasc/chalk');

const chalk = new Chalk.constructor({
  wrapper: {
    pre: '\1',
    post: '\2',
  }
});
0
mpen

Donc, je viens d'avoir le même problème avec une légère torsion et j'ai pensé partager ma solution aussi, juste pour ajouter ma petite nuance: D

Ma PS1 initiale était

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$"

Le problème que j'ai eu était que j'essayais de changer mon terminal title ainsi que l'invite de commande. Pour ce faire, j'ai ajouté \[\033]0;\]Title\a à la variable PS1.

Alors maintenant, ma PS1 était:

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[\033]0;\]Title\a"

Cette foutue la ligne d'emballage pour moi. J'ai finalement compris que bash ne semble pas aimer avoir \a à la fin. Pour contourner cela, j'ai mis le titre dans une variable, qui semblait le réparer.

TITLE="\033]0;Title\a"
PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[$TITLE\]"
0
Ciarán J. Hagen

J'ai eu ce problème quand je suis connecté à tmux. Le problème était que j'avais une session ipython en arrière-plan (ctrl + z) et que, d'une manière ou d'une autre, la rupture de ligne était brisée. Dès que je l'ai terminé (fg, ctrl+d+d), mon terminal a commencé à fonctionner correctement

Donc, recherchez les invites interactives arrêtées.

0