Ich passe mein zsh an PROMPT
und rufe eine Funktion auf, die echo
basierend auf dem Status einer Umgebungsvariablen eine Zeichenfolge sein kann oder nicht :
function my_info {
[[ -n "$ENV_VAR"]] && echo "Some useful information\n"
}
local my_info='$(my_info)'
PROMPT="${my_info}My awesome prompt $>"
Ich möchte, dass die Informationen in einer nachfolgenden neuen Zeile enden, damit sie, wenn sie festgelegt sind, in einer eigenen Zeile angezeigt werden:
Some useful information
My awesome prompt $>
Wenn es jedoch nicht festgelegt ist, soll sich die Eingabeaufforderung in einer einzelnen Zeile befinden, um eine leere Zeile zu vermeiden, die durch eine bedingungslose neue Zeile in meiner Eingabeaufforderung verursacht wird:
PROMPT="${my_info} # <= Don't want that :)
My awesome prompt $>"
Derzeit arbeite ich daran $(command substitution)
, meine neue Zeile zu entfernen, indem ich sie mit einem nicht druckbaren Zeichen versehen muss, damit die neue Zeile nicht mehr nachläuft:
[[ -n "$ENV_VAR"]] && echo "Some useful information\n\r"
Dies ist offensichtlich ein Hack. Gibt es eine saubere Möglichkeit, eine Zeichenfolge zurückzugeben, die auf einer neuen Zeile endet?
Bearbeiten: Ich verstehe, was den Verlust der nachfolgenden Zeilenumbruch verursacht und warum dies geschieht , aber in dieser Frage möchte ich speziell wissen, wie dieses Verhalten verhindert werden kann (und ich glaube nicht, dass diese Problemumgehung in meinem Fall zutrifft, da ich es bin auf der Suche nach einer "bedingten" Newline).
Bearbeiten: Ich stehe korrigiert da: Die referenzierte Problemumgehung könnte tatsächlich eine ziemlich nette Lösung sein (da das Präfixieren von Zeichenfolgen in Vergleichen ein allgemeines und etwas ähnliches Muster ist), außer ich kann es nicht richtig zum Laufen bringen:
echo "Some useful information\n"x
[...]
PROMPT="${my_info%x}My awesome prompt $>"
streift x
mir nicht das Schleppen ab .
Bearbeiten: Das Anpassen der vorgeschlagenen Problemumgehung an die Verrücktheit, die eine sofortige Erweiterung bedeutet, hat bei mir funktioniert:
function my_info {
[[ -n "$ENV_VAR"]] && echo "Some useful information\n"x
}
local my_info='${$(my_info)%x}'
PROMPT="$my_info My awesome prompt $>"
Sie sind der Richter, wenn dies eine bessere Lösung als die ursprüngliche ist. Es ist ein bisschen expliziter, denke ich, aber es fühlt sich auch etwas weniger lesbar an.
echo
ing. Was bei dieser Frage nicht der Fall ist.Antworten:
Letzte Zeilenumbrüche werden aus Befehlsersetzungen entfernt. Selbst zsh bietet keine Option, um dies zu vermeiden. Wenn Sie also endgültige Zeilenumbrüche beibehalten möchten, müssen Sie dafür sorgen, dass es sich nicht um endgültige Zeilenumbrüche handelt.
Der einfachste Weg, dies zu tun, besteht darin, ein zusätzliches Zeichen (außer einem Zeilenumbruch) nach den Daten zu drucken, die Sie genau erhalten möchten, und dieses letzte zusätzliche Zeichen aus dem Ergebnis der Befehlsersetzung zu entfernen. Sie können optional eine neue Zeile nach diesem zusätzlichen Zeichen einfügen, die trotzdem entfernt wird.
In zsh können Sie die Befehlssubstitution mit der Zeichenfolgenmanipulation kombinieren, um das zusätzliche Zeichen zu entfernen.
Achten Sie in Ihrem Szenario darauf, dass dies
my_info
nicht die Ausgabe des Befehls ist, sondern ein Shell-Snippet, um die Ausgabe abzurufen, die ausgewertet wird, wenn die Eingabeaufforderung erweitert wird.PROMPT=${my_info%x}…
hat nicht funktioniert, weil das versucht, ein Finalex
aus dem Wert dermy_info
Variablen zu entfernen , aber es endet mit)
.In anderen Shells muss dies in zwei Schritten erfolgen:
In Bash könnten Sie nicht
my_info
direkt von anrufenPS1
; stattdessen müssten Sie es von anrufenPROMPT_COMMAND
.quelle
setopt promptsubst
in zsh benötigen${variables}
, damit diese in der Eingabeaufforderung erweitert werden.Sie können Ihre Funktion die Escape-Escape-Codes ausgeben lassen, sodass sie beim Erweitern in die neue Zeile umgewandelt wird.
quelle
$'\n'
Mechanismus ), aber es funktioniert nicht, da zsh nicht dehnt die resultierend\n
imPROMPT
string: /local my_info='$(my_info)'
? Versuchen Sie es ohne sie oder nurPROMPT="$(my_info) My awesome prompt $>"
PROMPT="Foo\nBar"
sich im Gegensatz zu nicht einmal aus$ ENV_VAR="Foo\nBar"; echo $ENV_VAR
. Die einfachen Anführungszeichen in der Zuweisung werden benötigt, damit der Ausdruck nicht erweitert wird, wenn die Datei bezogen wird, da die "Referenz", die die Variable enthält, jedes Mal aufgelöst werden sollte, wenn diePROMPT
Variable ausgewertet wird.