So verwenden Sie einen Zeilenumbruch im Befehl „read -p“ bei Verwendung von Variablen in der Eingabeaufforderungszeichenfolge

So verwenden Sie einen Zeilenumbruch im Befehl „read -p“ bei Verwendung von Variablen in der Eingabeaufforderungszeichenfolge

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:

1)https://stackoverflow.com/questions/4296108/wie-füge-ich-einen-zeilenumbruch-für-den-read-befehl-hinzu/4296147

2)https://stackoverflow.com/questions/12741529/wie man eine Zeile unterbricht und eine neue Zeile in Read P in Bash hinzufügt

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 bashdie -pOption nur in Verbindung mit -e(einer anderen bashErweiterung, die bash's readsich wie zsh's verhalten lässt vared) nützlich, wobei bashdie 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 .\nzur Ausgabe hinzugefügt. Durch die Befehlsersetzung wird das entfernt \nund wir entfernen das .mit und ${output%.}lassen die gesamte Befehlsausgabe übrig (vorausgesetzt, sie enthält keine NUL-Zeichen in anderen Shells als zshund es handelt sich um gültigen Text im aktuellen Gebietsschema in yash).

Zur Info: In anderen Korn-ähnlichen Shells readlautet 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 emacsoder set -o vi). zshunterstützt diese Syntax auch aus Kompatibilitätsgründen, aber der Zeileneditor wird nur für verwendet vared, nicht für readdort.


¹ 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

verwandte Informationen