Warum behält diese Bash-Eingabeaufforderung beim Scrollen im Verlauf manchmal einen Teil der vorherigen Befehle bei?

29

Meine Bash-Eingabeaufforderung, von der ich zugeben werde, dass sie von einigen Stellen gestohlen und zusammengeschustert wurde, fügt manchmal einen Teil der vorherigen Befehle zu ihrer Länge hinzu, wenn der Bash-Verlauf mit den Auf- / Ab-Pfeilen gescrollt wird.

Zum Beispiel, wenn meine vorherigen Befehle waren:

ls
cd /home/caleb
vim .bashrc

Wenn ich an meiner Eingabeaufforderung war und zweimal hochgescrollt habe, könnte es so aussehen:

$ vim .bcd / home / caleb

Wobei die ersten fünf Zeichen vom letzten Befehl übrig bleiben.

Hat jemand eine Idee, warum dies geschieht und wie es gestoppt werden kann?

Meine Eingabeaufforderung wird mit diesem Code festgelegt (viel zu lang, um ihn hier einzuschließen ): https://gist.github.com/1679352

Caleb Thompson
quelle
1
Setze PS1 auf einen Wert ohne den ganzen VCS-Mist und schau was passiert. Das ist meine Vermutung.
Daniel Beck
Haben Sie den Täter in Ihrer Aufforderung bereits gefunden? Ich habe das gleiche Problem.
ACME
Ja, bash verliert es bei Farben und ist nicht in der Lage, die Länge der Zeichenfolgen zu trennen, wenn die Farbe von der Länge der sichtbaren Zeichenfolge abweicht. Das war es, worauf SiegeX abzielte. Am Ende bin ich zu ZSH gewechselt und habe eine andere Eingabeaufforderung verwendet. ZSH hat nicht das gleiche Problem.
Caleb Thompson
1
Die beiden vorherigen Antworten haben mein Problem nicht gelöst und keine Erklärung dafür geliefert. Bitte überprüfen Sie, ob die benutzerdefinierte Bash-Eingabeaufforderung sich selbst überschreibt , wenn jemand bis zu diesem Punkt gesucht hat.
D3Hunter
Verwandte Ausgabe unix.stackexchange.com/questions/105958/…
matthiasbe

Antworten:

6

Irgendwo ist Ihre Aufforderung fubar. In der Regel geht Ihre Shell davon aus, dass sie nicht druckbare Termcodes ausgibt und Speicherplatz beansprucht. Der beste Rat, den ich Ihnen geben kann, ist, Ihre Eingabeaufforderung systematisch zu ergänzen (oder von ihr zu entfernen), bis dieses Verhalten aufhört, den Code zu isolieren, der dieses Problem verursacht.

SiegeX
quelle
37

Die Farbcodes müssen in eckige Klammern gesetzt werden. Die Klammern informieren bash, dass der beigefügte Text nicht gedruckt werden soll

Aufbauend auf dem Beispiel von @ Phreditor zeigt dies, dass jede Formatierung nach dem Zeilenumbruch zu dem ursprünglichen Problem führt:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\033[0;90m\$ "

Das Einschließen des Formatcodes in [] stellt sicher, dass kein störendes Verhalten auftritt:

export PS1="\n\[\[\033[01;33m\][\w]\[\033[00m\]\n\[\033[0;90m\]\$ "

Die Dokumentation: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/nonprintingchars.html

Da die PS1-Formatierung dazu führt, dass der Wert so lang und schwer lesbar ist, habe ich die Formatcodes in Variablen eingefügt:

BYELLOW='\[\033[01;33m\]'
IBLACK='\[\033[0;90m\]'
PS_CLEAR='\[\033[0m\]'
export PS1="\n${BYELLOW}[\w]${PS_CLEAR}\n${IBLACK}\$ "
m79lkm
quelle
3
Dies sollte die akzeptierte Antwort sein. Habe das Problem gelöst.
Atcold
1
Es sollte beachtet werden (weil ich es nicht bemerkt habe;)), dass in diesem Durcheinander von Backslashes und eckigen Klammern die eckigen Klammern, die der Escape-Sequenz folgen, \033NICHT maskiert werden sollten. Es dürfen nur die umhüllenden eckigen Klammern entfernt werden.
Benjam
Die Art und Weise, wie ich mich mit all diesen Sonderzeichen auseinandergesetzt habe, hat mir geholfen, anhand des ersten Google-Ergebnisses eine funktionierende Eingabeaufforderung zu generieren, die genau meinen
Wünschen entsprach
Ich wollte meine prompten Farben für JAHRE anpassen, hatte dies aber noch nie, da ich immer dieses Problem hatte! Ich konnte nie herausfinden, warum, also habe ich einfach angehalten und alles weiß gehalten ... Ich habe gerade einen neuen Computer eingerichtet und es dämmerte mir schließlich, das Problem tatsächlich einmal zu googeln ... Ich bin so froh, dass ich es getan habe! Vielen Dank für diese wundervolle Lektion.
TylerH4
8

Ich hatte das gleiche Problem und es hing mit den Farbdefinitionen zusammen.

In meinem Fall habe ich eine mehrzeilige Eingabeaufforderung (bietet den meisten Platz für den aktuellen Befehl, unabhängig von der von der Eingabeaufforderung angezeigten Pfadlänge).

Schlechte Version:

export PS1="\n\n\[\033[01;33m[\w]\n\033[00m\$ "

Gute Version:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\$ "

\033[00mbeendet die Farbe. Befindet es sich hinter der neuen Zeile ( \n), wird das korrekte Neuzeichnen im Terminal verhindert, um vorherige Befehle mit Hintergrundfarbe zu überschreiben. Das Verschieben hinter die neue Zeile löste das Problem.

(Verwenden von Terminal unter Mac OS 10.8)

Phreditor
quelle
Dies machte das Problem für mich deutlich, während die derzeit akzeptierte Antwort zu allgemein war.
Brian
Dies ist die präzisere Antwort und sollte der Gewinner sein (und war auch die Lösung für mein Problem).
Craveytrain
Das \nwar auch der Schuldige für mich. Vielen Dank!
mhulse
3

Ich denke tatsächlich, dass dies mit einem fehlenden Trennzeichen für nicht druckbare Zeichen zu tun hat. Ich hatte genau das gleiche Problem, aber das Verschieben vor dem Zeilenwechsel (\ n) hat es nicht behoben. Stattdessen habe ich alle nicht druckbaren Zeichen (hier Farbbefehle) korrekt mit '\ [' und '\]' umgeben.

Schlecht (funktioniert, hat aber das oben beschriebene Problem mit dem Verlaufspülung):

PS1="\e[32m\u\e[35m@\e[32m\h \e[33m\w\e[36m\n\$\e[0m"

Gut (Umgeben von allen Farbbefehlen mit '\ [' und '\]' - zeigt den Verlauf der gestampften Befehle nicht an):

PS1="\[\e[32m\]\u\[\e[35m\]@\[\e[32m\]\h \[\e[33m\]\w\[\e[36m\]\n\$\[\e[0m\]"

i.e. "\e[...m" --becomes--> "\[\e[...m\]"

Und wenn Sie dies in so etwas wie SecureCRT setzen, um es bei der Anmeldung an ein System automatisch zu senden, müssen Sie möglicherweise alles doppelt maskieren (überall doppelte Backslashes setzen), wenn das automatische Anmeldesystem den ersten Backslash selbst verwendet, um das zu sendende Zeichen zu bestimmen :

PS1="\\[\\e[32m\\]\\u\\[\\e[35m\\]@\\[\\e[32m\\]\\h \\[\\e[33m\\]\\w\\[\\e[36m\\]\\n\\$\\[\\e[0m\\]"

i.e. "\..." --becomes--> "\\..."

(Dies gilt auf jeden Fall für SecureCRT und möglicherweise auch für andere, z. B. PuTTY oder TeraTerm - Tests, die Ihrerseits erforderlich sind.)

Skeetastax
quelle