Ich möchte einen Zeilenumbruch nach der Eingabeaufforderung haben, während ich die Funktion cowsay in der Eingabeaufforderung verwende:
read -p "$(cowsay "do you know this word?") \n" answer
Auf dieses Problem gibt es mehrere Antworten:
Die Antworten verwenden jedoch die Notation, die den Befehl ''
nicht auflöstcowsay
Antwort1
Warum würden Sie die Option verwenden -p
, für die Sie die Shell benötigen würden bash
?
Mach einfach:
cowsay "do you know this word?"
read answer
In ist bash
die -p
Option nur in Verbindung mit -e
(einer anderen bash
Erweiterung, die bash
's read
sich wie zsh
's verhalten lässt vared
) nützlich, wobei bash
die Eingabeaufforderung in einigen Fällen neu gezeichnet werden muss (z. B. bei Ctrl+L). Aber dann würden Sie diese Eingabeaufforderung wahrscheinlich nicht neu zeichnen müssen oder wollen, wenn sie mehrere Zeilen umfasst.
Wenn Sie möchten, können Sie jederzeit Folgendes tun:
read -ep "$(cowsay "do you know this word?")"$'\n' answer
(hier wird $'...'
die Anführungszeichenform von ksh93 verwendet, die C-ähnliche Escape-Sequenzen versteht)
oder
read -ep "$(cowsay "do you know this word?")
" answer
Allgemeiner gesagt besteht das Problem darin, dass durch die Befehlsersetzung Zeilenumbruchzeichen (nicht nur eins, sondern alle, was als Fehler/Fehlfunktion¹ angesehen werden könnte) am Ende der Befehlsausgabe entfernt werden.
Um dies zu umgehen, besteht der übliche Trick darin:
output=$(cowsay "do you know this word?"; echo .)
output=${output%.}
read -p "$output" answer
Das heißt, es wird .\n
zur Ausgabe hinzugefügt. Durch die Befehlsersetzung wird das entfernt \n
und wir entfernen das .
mit und ${output%.}
lassen die gesamte Befehlsausgabe übrig (vorausgesetzt, sie enthält keine NUL-Zeichen in anderen Shells als zsh
und es handelt sich um gültigen Text im aktuellen Gebietsschema in yash
).
Zur Info: In anderen Korn-ähnlichen Shells read
lautet die Syntax zum Ausgeben einer eigenen Eingabeaufforderung wie folgt:
read 'answer?prompt: '
Die Korn-Shell würde diese Eingabeaufforderung auch neu zeichnen, wenn vom Terminal gelesen wird und eine Editoroption aktiviert wurde (wie mit set -o emacs
oder set -o vi
). zsh
unterstützt diese Syntax auch aus Kompatibilitätsgründen, aber der Zeileneditor wird nur für verwendet vared
, nicht für read
dort.
¹ zum Beispiel macht es Dinge wie basename=$(basename -- "$file")
falsch, da es Zeilenumbruchzeichen vom Ende des Dateinamens entfernen könnte, nicht nur das, das vonbasename