Die Verwendung von echo -e in PS1 verursacht Zeilenumbruchprobleme in der Shell

Die Verwendung von echo -e in PS1 verursacht Zeilenumbruchprobleme in der Shell

Die Probleme:

Öffnen Sie die Eingabeaufforderung der Eingabeaufforderung:

Bildbeschreibung hier eingeben

Geben Sie den Buchstaben a mehrfach ein:

Bildbeschreibung hier eingeben

Anstatt in eine neue Zeile umzubrechen, wird der eingegebene Text in dieselbe Zeile umbrochen:

Bildbeschreibung hier eingeben

Drücken Sie nun b. Wenn ein Zeilenumbruch zum zweiten Mal erforderlich ist, erfolgt ein Zeilenumbruch:

Bildbeschreibung hier eingeben


Was verursacht dieses Verhalten?

Die Verwendung einer PS1 auf diese Weise verursacht das folgende Verhalten:

ps1Color="\033[1;35m"
export PS1='$(echo -en $ps1Color) Baz $'

Beachten Sie, dass der Grund, warum ich Echo anstelle der Farbe direkt verwenden möchte, darin besteht, dass ich die Farbe bedingt basierend auf dem Beendigungsstatus des vorherigen Befehls hinzufügen möchte..

Die direkte Verwendung der Farbe führt nicht zu diesem Verhalten.


Meine Fragen sind:

  • Wie kann ich Farbcodes zur Verwendung in einer PS1 drucken?Echo verwenden?
  • Wie gehe ich am besten vor, wenn ich meiner PS1 bedingt eine andere Farbe verleihen möchte?
  • Warum sehe ich dieses Verhalten?

Aktualisieren

Um es klar zu sagen, ich möchte dies wirklich mit Echo tun, weil ich die Farbe ändern möchtebedingt.

Das ist, was ich derzeit im Moment habe:

function setPs1Colors_start () {

    local previousExit=$?

    local ps1Color="\033[1;35m"
    local ps1FailBackground="\e[41m"

    echo -en $ps1Color

    if [[ previousExit -ne 0 ]]
    then
        echo -en $ps1FailBackground
    fi

}

function setPs1Colors_end () {
    local ps1DefaultColor="\033[0m"
    echo -en $ps1DefaultColor
}

export PS1='$(setPs1Colors_start)[$(date +%b\-%d\ %k:%M)][$(versionControlInfo)\W]\$$(setPs1Colors_end) '

Antwort1

\033[1;35mbeträgt 7 Zeichen. bashkann nicht erraten, dass diese 7 Zeichen tatsächlich eine Breite von Null haben. Wenn nicht, wird angenommen, dass sie 7 Spalten breit sind.

Es (oder vielmehr readlineder zugrunde liegende Zeileneditor, den es verwendet) möchte die aktuelle Position auf dem Bildschirm kennen, da es Cursorpositionierungssequenzen (hoch, runter, links, rechts) verwendet, um den Cursor zu bewegen, wenn Sie Bearbeitungstasten verwenden.

Sie müssen also angeben, welche Zeichen in der Eingabeaufforderung den Cursor nicht bewegen. bashDies geschieht mit , indem Sie \[...\]der Shell mitteilen, dass der Inhalt die Breite Null hat.

Beachten Sie auch, dass die Eingabeaufforderungserweiterung in als ESC-Zeichen basherkannt wird \e, Sie müssen also nicht verwenden echo -e. Sie können einfach Folgendes tun:

PS1='\[\e[1;35m\] blah $ '

echoWenn Sie oder besser verwenden müssen printf, gehen Sie wie folgt vor:

PS1='\[$(if ...; then printf "$color1"; fi)\] blah $ '

Oder:

PS1='$(if ...; then printf "\[$color1\]"; fi) blah $ '

In ist zshdas Äquivalent von bash's wie in , enthält aber Anweisungen zum Ändern von Zeichenattributen. Daher würden Sie dort lieber Folgendes tun:\[...\]%{...%}tcshzsh

PS1='%B%F{magenta}blah $ '

Für fett-magentafarbenen Vordergrund. Es gibt auch einige Formen von bedingten Tests, einschließlich on $?, sodass Ihr redif error, green otherwise wie folgt geschrieben werden könnte:

PS1='%F{%(?:green:red%)}blah%f $ '

tcshhat %B, aber nicht %F{color}. Hier würden Sie also Folgendes verwenden:

set prompt = '%{\e[1;35m%}blah $ '

In ksh88oder pdkshwürden Sie Folgendes tun:

PS1=$(printf '\5\r\5\33[1;35m\5blah $ ')

Damit wird ein Zeichen (hier 0x5) alsFluchtZeichen. Indem Sie dann Text zwischen zwei von ihnen einschließen, teilen Sie der Shell mit, dass er nicht sichtbar ist. Sie können jedes beliebige Zeichen außer 0x5 verwenden, es darf jedoch sonst nicht in Ihrer Eingabeaufforderung vorkommen und muss, außer in mksh, vom Terminal ignoriert werden, da die Shell es tatsächlich schreibt (zusammen mit dem CR-Zeichen).

ksh93verwendet nur eine Cursorpositionierungssequenz: BS(die den Cursor eine Spalte nach links bewegt). Um nach rechts zu gehen, werden einfach die gleichen Zeichen neu gezeichnet. Es muss also nicht die Cursorposition kennen, sondern nur die Breite jedes eingegebenen Zeichens. Das funktioniert, solange das Terminal selbst am Rand umbricht (funktioniert also nicht richtig mit diesemterminatorzum Beispiel). Ein Nebeneffekt einer Eingabeaufforderung mit Steuersequenzen besteht darin, dass Ihre Tabulatoren nicht richtig ausgerichtet sind.

verwandte Informationen