Ich habe diese mehrzeilige Zeichenfolge (Anführungszeichen enthalten):
abc'asdf"
$(dont-execute-this)
foo"bar"''
Wie würde ich es einer Variablen mit einem Heredoc in Bash zuweisen?
Ich muss Zeilenumbrüche beibehalten.
Ich möchte den Zeichen in der Zeichenfolge nicht entkommen, das wäre ärgerlich ...
'EOF'
, mit` in the content: if the second line has
Escape- Zeilenumbrüchen mit dem Befehl cd`. Ich erhalte zurück: " .sh: Zeile X: Befehl cd: Befehl nicht gefunden "; aber wenn ich doppelt zitiere"EOF"
; dann werden Bash-Variablen${A}
nicht als Zeichenfolgen beibehalten (sie werden erweitert); aber dann, Zeilenumbrüche werden erhalten - und ich habe keine Probleme , einen Befehls mit fliessendcd
in der zweiten Zeile ( und sowohl ‚EOF‘ und „EOF“ scheint gut auch zu spieleneval
, für den Betrieb eine Reihe von Befehlen gespeichert in eine Stringvariable ). Prost!"EOF"
Variablen mit doppelter Qout-Funktion führen bei einem Aufruf von via dazueval $VAR
, dass der gesamte Rest des Skripts kommentiert wird, da hier $ VAR als einzelne Zeile angezeigt wird ;; Um Bash-#
Kommentare in mehrzeiligen Skripten verwenden zu können, wird das doppelte Anführungszeichen auch in dereval call:
Bewertung "$ VAR" `angegeben.eval
dieser Methode, habe sie aber nicht gefunden, da sie Teil eines Pakets war, desseneval
Variablen in der Konfigurationsdatei definiert sind. Fehlermeldung war :/usr/lib/network/network: eval: line 153: syntax error: unexpected end of file
. Ich habe gerade zu einer anderen Lösung gewechselt.Antworten:
Sie können eine unnötige Verwendung von nicht
cat
übereinstimmenden Anführungszeichen vermeiden und besser damit umgehen:Wenn Sie die Variable beim Echo nicht zitieren, gehen Zeilenumbrüche verloren. Wenn man es zitiert, bleiben sie erhalten:
Wenn Sie Einrückungen zur besseren Lesbarkeit im Quellcode verwenden möchten, verwenden Sie einen Bindestrich nach den weniger als. Das Einrücken darf nur mit Tabulatoren (keine Leerzeichen) erfolgen.
Wenn Sie stattdessen die Registerkarten im Inhalt der resultierenden Variablen beibehalten möchten, müssen Sie die Registerkarte aus entfernen
IFS
. Die Terminalmarkierung für das hier doc (EOF
) darf nicht eingerückt werden.Tabulatoren können in der Befehlszeile durch Drücken von Ctrl- eingefügt werden V Tab. Wenn Sie einen Editor verwenden, funktioniert dieser möglicherweise auch, oder Sie müssen möglicherweise die Funktion deaktivieren, mit der Tabulatoren automatisch in Leerzeichen konvertiert werden.
quelle
set -o errexit
(akaset -e
) in Ihrem Skript haben und dies verwenden, es Ihr Skript beendet, weil esread
einen Rückkehrcode ungleich Null zurückgibt, wenn es EOF erreicht.set -e
und immer gegen seine Verwendung empfehle. Es ist besser, stattdessen die richtige Fehlerbehandlung zu verwenden.trap
ist dein Freund. Andere Freunde:else
und||
unter anderem.cat
in einem solchen Fall wirklich? Das Zuweisen eines Heredocs zu einer Variablen mitcat
ist eine bekannte Redewendung. Irgendwieread
verschleiert die Verwendung von Dingen für wenig Nutzen imho.d
und der leeren Zeichenfolge kein Leerzeichen steht .bash
kollabiert-rd''
zu einfach-rd
bevorread
jemals seine Argumente gesehen werden, wird alsoVAR
als das Argument zu behandelt-d
.read
wird mit einem Exit-Code ungleich Null zurückgegeben. Dies macht diese Methode in einem Skript mit aktivierter Fehlerprüfung (zset -e
. B. ) weniger als ideal .Verwenden Sie $ (), um die Ausgabe
cat
Ihrer Variablen wie folgt zuzuweisen :Stellen Sie sicher, dass das Starten von END_HEREDOC durch einfache Anführungszeichen begrenzt wird.
Beachten Sie, dass das Ende des Heredoc-Trennzeichens
END_HEREDOC
in der Zeile stehen muss (daher steht die Endklammer in der nächsten Zeile).Danke
@ephemient
für die Antwort.quelle
echo "$VAR"
stattecho $VAR
.ash
und OpenWRT, woread
nicht unterstützt-d
.Dies ist eine Variation der Dennis-Methode, sieht in den Skripten eleganter aus.
Funktionsdefinition:
Verwendungszweck:
genießen
ps hat eine 'read loop'- Version für Shells erstellt, die nicht unterstützt werden
read -d
. sollte mitset -eu
und ungepaarten Backticks funktionieren , aber nicht sehr gut getestet:quelle
read
Schleife in der Funktion, um den-d ''
Bashismus zu vermeiden, der zum Beibehalten von Zeilenumbrüchen erforderlich ist).set -e
set, die ausgewählte Antwort jedoch nicht. Es scheint wegenhttp://unix.stackexchange.com/a/265151/20650
funktioniert nicht, weil Sie stdin auf etwas umleiten, das ihm egal ist, nämlich die Zuweisung
funktioniert, aber es gibt einen Hintergrund, der Sie möglicherweise davon abhält, dies zu verwenden. Außerdem sollten Sie Backticks wirklich vermeiden. Verwenden Sie besser die Befehlsersetzungsnotation
$(..)
.quelle
$(cat <<'END'
stattdessen. @Neil: Der allerletzte Zeilenumbruch wird nicht Teil der Variablen sein, der Rest bleibt jedoch erhalten.echo "$A"
wenn Sie schreiben (dh $ A in doppelte Anführungszeichen setzen), sehen Sie die Zeilenumbrüche!REM=<< 'REM' ... comment block goes here ... REM
. Oder kompakter: << 'REM' ...
. Wo "REM" so etwas wie "NOTES" oder "SCRATCHPAD" usw. sein könnteDies ist nicht wahr - Sie werden wahrscheinlich nur durch das Verhalten des Echos in die Irre geführt:
echo $VAR # strips newlines
echo "$VAR" # preserves newlines
quelle
Wenn Sie Neils Antwort abzweigen , benötigen Sie häufig überhaupt keine Variable. Sie können eine Funktion ähnlich wie eine Variable verwenden und sie ist viel einfacher zu lesen als die Inline- oder
read
basierten Lösungen.quelle
Ein Array ist eine Variable. In diesem Fall funktioniert die Map-Datei
Dann können Sie so drucken
quelle
Weisen Sie einer Variablen einen Heredoc-Wert zu
wird als Argument eines Befehls verwendet
quelle
echo "$VAR"
Ich musste einen String mit NULL lesen. Hier ist eine Lösung, die alles liest, was Sie darauf werfen. Wenn Sie sich jedoch tatsächlich mit NULL beschäftigen, müssen Sie sich auf Hex-Ebene damit befassen.
$ cat> read.dd.sh.
Beweis:
HEREDOC-Beispiel (mit ^ J, ^ M, ^ I):
quelle
Dank der Antwort von dimo414 zeigt dies, wie seine großartige Lösung funktioniert, und zeigt, dass Sie auch leicht Anführungszeichen und Variablen im Text haben können:
Beispielausgabe
test.sh
quelle
quelle