Wie bringe ich lange Befehlszeilen dazu, in die nächste Zeile zu wechseln?

108

Etwas, das ich in Ubuntu seit langem bemerkt habe und das mich frustriert hat, ist, wenn ich einen Befehl in der Befehlszeile eingebe, der länger (breiter) als die Terminalbreite ist, anstatt in eine neue Zeile zu brechen Spalte 1 in derselben Zeile und überschreibt den Anfang meiner Befehlszeile. (Der eigentliche Befehl wird nicht überschrieben, aber der angezeigte Text wird visuell überschrieben.)

Es ist schwer zu erklären, ohne es zu sehen, aber nehmen wir an, mein Terminal war 20 Zeichen breit (meins ist mehr wie 120 Zeichen - nur zum Beispiel), und ich möchte das englische Alphabet wiederholen. Was ich tippe ist das:

echo abcdefghijklmnopqrstuvwxyz

Aber wie mein Terminal aussieht, bevor ich die Taste drücke, ist:

pqrstuvwxyzghijklmno

Wenn ich die Eingabetaste drücke, ertönt ein Echo

abcdefghijklmnopqrstuvwxyz

Ich weiß also, dass der Befehl ordnungsgemäß empfangen wurde. Es hat meine Eingabe nach dem "o" einfach umbrochen und in derselben Zeile von vorne begonnen.

Was ich erwarten würde, wenn ich diesen Befehl auf einem Terminal mit einer Breite von nur 20 Zeichen eingeben würde, wäre dies:

echo abcdefghijklmno
pqrstuvwxyz

Hintergrund: Ich verwende bash als Shell und habe diese Zeile in meinem ~ / .bashrc:

set -o vi

in der Befehlszeile mit VI-Befehlen navigieren zu können. Ich verwende derzeit Ubuntu 10.10 Server und verbinde mich mit dem Server mit Putty.

In jeder anderen Umgebung, in der ich gearbeitet habe, wird, wenn ich eine lange Befehlszeile eingebe, eine neue Zeile unter der Zeile eingefügt, in der ich gerade arbeite, wenn mein Befehl länger als die Terminalbreite ist und wenn ich weiter tippe, kann ich meinen Befehl sehen 2 verschiedene Zeilen. Aber solange ich mich erinnern kann, Ubuntu verwendet zu haben, belegen meine langen Befehle nur 1 Zeile.

Dies passiert auch, wenn ich zu vorherigen Befehlen im Verlauf zurückkehre (ich drücke Esc, dann 'K', um zu vorherigen Befehlen zurückzukehren) - wenn ich zu einem vorherigen Befehl komme, der länger als die Terminalbreite war, wird die Befehlszeile aufgerufen verstümmelt und ich kann nicht sagen, wo ich im Befehl bin.

Die einzige Abhilfe, die ich gefunden habe, um den gesamten langen Befehl zu sehen, ist das Drücken von "Esc-V", wodurch der aktuelle Befehl in einem VI-Editor geöffnet wird.

Ich glaube nicht, dass ich etwas Seltsames in meiner .bashrc-Datei habe. Ich habe die Zeile "set -o vi" auskommentiert und hatte immer noch das Problem.

Ich habe eine neue Version von Putty heruntergeladen und keine Änderungen an der Konfiguration vorgenommen. Ich habe nur meinen Hostnamen eingegeben, um eine Verbindung herzustellen, und ich habe immer noch das Problem einige Konfigurationsänderungen vornehmen)

Hat jemand anderes dieses Problem gehabt und kann sich jemand vorstellen, wie man es behebt?

Bearbeiten

Es war meine .bashrc-Datei. Ich habe das gleiche Profil von Computer zu Computer kopiert und Sonderzeichen in meiner PS1 verwendet, die es irgendwie abschrecken. Ich halte mich jetzt an die Standard-Bash-Variablen für meine PS1.

Danke an @ ændrük für den Tipp zum .bashrc!

... Bearbeiten beenden ...

BrianH
quelle
1
Um sicherzugehen, dass das Problem nicht durch Ihre .bashrc-Datei verursacht wird, würde ich empfehlen, sie vorübergehend durch eine Kopie von zu ersetzen /etc/skel/.bashrc. Denken Sie daran, dass Sie erneut eine Verbindung herstellen müssen, damit die Änderungen wirksam werden, und stellen Sie sicher, dass Sie eine Sicherungskopie Ihrer eigenen .bashrc-Datei erstellen.
ændrük
1
Welche Terminalanwendung verwenden Sie? Das Verhalten, das Sie beschreiben, ist nicht üblich, schon gar nicht voreingestellt.
João Pinto
In Shells, in denen ich gearbeitet habe (und in Cisco CLI), können Sie auch Strg-L eingeben, um die eingegebene Zeile erneut anzuzeigen, auch wenn sie sich außerhalb des Bildschirms befindet. In Ihrer Situation kann das immer noch die fehlerhafte Ausgabe erzeugen, von der Sie sprechen, aber ich wäre neugierig.
Belacqua
3
Fühlen Sie sich frei, eine "Antwort" zu erstellen, die die Lösung erklärt, und sie als akzeptiert zu markieren. Es mag ein wenig albern erscheinen, aber eine richtige Antwort hilft dabei, die Site organisiert zu halten und andere, die in Zukunft ähnliche Probleme haben, effektiver anzuleiten.
ændrük
Verwenden tput smam
Sie

Antworten:

136

Stellen Sie sicher, dass alle nicht druckbaren Bytes in Ihrer PS1 enthalten sind \[ \]. Andernfalls zählt bash sie in der Länge der Eingabeaufforderung. Anhand der Länge der Eingabeaufforderung wird festgelegt, wann die Zeile umgebrochen werden soll.

In diesem Beispiel zählt bash die Eingabeaufforderung als 19 Spalten breit, während die vom Terminal angezeigte Eingabeaufforderung nur 10 Spalten breit ist ( My promptin Cyan und >in Standardfarbe geschrieben):

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

Während hier nur die Eingabeaufforderung als 10 Spalten breit gezählt wird, werden die Bytes zwischen dem Sonderzeichen \[und dem \]Escapezeichen ignoriert :

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

Für eine gute Praxis verwenden Sie jedoch tput, um die Terminal-Escapes zu generieren, anstatt sie hart zu codieren:

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

Siehe http://mywiki.wooledge.org/BashFAQ/053 , und auch http://wiki.bash-hackers.org/scripting/terminalcodes für mehr auf tput.

geirha
quelle
3
Das ist eine großartige Erklärung für das Problem, das die akzeptierte Antwort nicht liefert
Jamie Cook,
In der letzten Codezeile PS1='...': Warum verhindern $cyanund verhindern einfache Anführungszeichen nicht die $resetErsetzung?
Andrybak
2
@andrybak, verhindern $cyanund verhindern $resetdas Ersetzen, werden jedoch PS1jedes Mal ausgewertet, wenn die Eingabeaufforderung gedruckt wird. Sie können dies feststellen, indem Sie versuchen PS1='$var> ', varverschiedene Werte einzugeben und zu überprüfen, wie sich die Eingabeaufforderung ändert. Versuchen Sie dann festzustellen PS1="$var> " , dass die Eingabeaufforderung statisch bleibt. $varWurde während der Zuweisung erweitert, wird nicht jedes Mal PS1ausgewertet.
Geirha
1
Das ist großartig. Vielen Dank für das Posten! Es erleichtert und verbessert die Lesbarkeit der eckigen Klammern.
Phyatt
Wie ich tun , um diese Arbeit machen PS1=${PS1}"\e]2;$@\a". Ich habe es versuchtPS1=${PS1}"\[\e]2;\]$@\[\a\]"
Ramana Reddy
59

Ich denke du hast deine PS1mit Farben konfiguriert , oder?

Stellen Sie einfach sicher, dass Sie \[in Ihrem PS1Zitat vor Ihrem Farbsatz haben

Zum Beispiel:

PS1='\[\e[0;32m\u@\w/:\[\e[m '
wjandrea
quelle
Meine PS1 war export PS1='^[[96m'$(hostname)'<^[[92m${PWD}^[[96m>^[[97m '- ich benutze sie schon lange - KSH-kompatibel ...
BrianH
2
Beeindruckend. Ich benutze seit Ewigkeiten Terminal-Eingabeaufforderungen und hatte dieses Problem noch nie zuvor. Hätte das nie herausgefunden. Vielen Dank.
Bchurchill
3
Wenn Sie \ [verwenden, während Sie einfache Anführungszeichen verwenden, erhalten Sie einen unbeabsichtigten Schrägstrich. Außerdem sollte] am Ende der magischen Zeichen verwendet werden, wie in der am besten
bewerteten
2
-1 Funktioniert nicht. Sie müssen wickeln den Nicht-Druckabschnitt mit \[am Anfang und \]am Ende.
wjandrea
@ igorsantos07 Der doppelte Backslash in \\[war ein Tippfehler, der durch eine Bearbeitung verursacht wurde. Ich habe es behoben.
wjandrea
11

Ich hatte ein ähnliches Problem und fand schließlich eine einfache Lösung.

Fügen Sie folgende Zeile in Ihre .bashrcDatei ein:

COLUMNS=250

Geben source ~/.bashrcSie dann den gewünschten Effekt ein.

Deboshree
quelle
In einigen Fällen, z. B. bei engen Terminatorunterteilungen, liegt das Problem nicht in den Promt-Farbzeichen, sondern nur in einem falschen COLUMNS-Wert. Diese Antwort brachte mich aus einem sehr störenden Loch heraus!
Carles Sala
1
Abmelden ist nicht erforderlich. Tun source .bashrc. Ihre
Anfrage
1
Ich fand , dass ich da nicht shopt habe setwinsizeSet für meine bash, so war es nicht SäULEN Updates verfügt , siehe unix.stackexchange.com/a/167911/8337
rogerdpack
1
Ich habe export COLUMNS=250gefolgt export TERM=xtermund es war glücklich.
Philip Kearns
5

Ich hatte das gleiche Problem mit einer benutzerdefinierten farbigen Eingabeaufforderung, obwohl ich Farbcodes in \[und \]Trennzeichen enthielt . Es stellt sich heraus, dass Bash Probleme mit der Farbwiedergabe innerhalb einer Funktion hat . Am Ende habe ich nur Variablen für meine Eingabeaufforderung verwendet, und obwohl mein .bashrc etwas weniger elegant ist, funktioniert jetzt alles gut.

reentim
quelle
Wenn jemand dies noch liest, ist es tatsächlich möglich, Farben in einer Funktion zu umgehen. Siehe diese Antwort auf die verknüpfte Frage.
wjandrea
3

Es ist ganz einfach, vor dem Einstellen der PS1 die folgende Zeile einzufügen:

stty columns 1000

Zum Beispiel,

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

Dies betrifft jedoch auch andere Unix-Befehle wie ls und man.

Gennady
quelle
1
Das funktioniert in OSX.
Raskhadafi
4
Dies wirkt sich auch sehr stark auf vim aus. Bitte benutze das nicht.
28.
0

Ich hatte dieses Problem, als ich in tmux verbunden war. Das Problem war, dass ich eine ipythonSitzung im Hintergrund hatte ( ctrl + z) und irgendwie Zeilenumbruch brach. Sobald ich es ( fg, ctrl+d+d) beendet habe , hat mein Terminal ordnungsgemäß funktioniert

Suchen Sie daher nach angehaltenen interaktiven Eingabeaufforderungen.

Ciprian Tomoiagă
quelle
0

Also hatte ich nur das gleiche Problem mit einer leichten Wendung und ich dachte, ich würde auch meine Lösung teilen, nur um meine kleine Nuance hinzuzufügen: D

Meine anfängliche PS1 war

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

Das Problem , das ich hatte , war , dass ich versuche , meinen Terminal zu ändern Titel sowie die Eingabeaufforderung. Das habe ich durch Hinzufügen \[\033]0;\]Title\azur PS1- Variablen gemacht.

So, jetzt war meine PS1:

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

Das hat den Zeilenumbruch für mich durcheinander gebracht. Ich habe endlich herausgefunden, dass Bash \aam Ende nicht gerne zu haben scheint . Um dies zu umgehen, habe ich den Titel in eine Variable eingefügt, die ihn zu korrigieren schien.

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

\[ und \] hat nicht für mich gearbeitet. Ich vermute, dass es etwas anderes gab, als ich die Eingabeaufforderung (aus einem externen Programm) generiert habe, oder weil meine Eingabeaufforderung "dynamisch" war.

Nachdem ich dies gelesen hatte, stellte ich fest, dass man die Farbcodes tatsächlich mit den 0x01und 0x02Bytes umgehen kann.

ZB verwende ich eine spezielle Version von Kreide und wickle die Farben folgendermaßen um:

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

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