Warum scheinen "echo -e" -Befehle nicht die richtige Ausgabe zu liefern?

21

Im Terminal von Ubuntu 18.04 LTS, wenn ich diesen Befehl schreibe:

echo -e "Hello\\\n"

Es gibt dies als Ausgabe:

Hello\n

Aber es sollte drucken, wie der Mann Seite sagt:

Hello\

Das heißt, zuerst drucken Hello, dann \ein Newline-Zeichen (und dann eine weitere Newline). Wo ist das Problem?

Siehe diese wenigen echo -eBefehle und ihre Ausgabe :

man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n
yolin00
quelle
yes.for ersten 2 \ es ausgeben sollte ein \ .und letzten \ n und einen Backslash Escape machen \ n (neue Zeile) .so warum es sollte Hallo drucken \
yolin00
1
Versuchen Sie es ohne Anführungszeichen.
Ajgringo619
2
Eine erstaunliche Antwort wurde von Eliah Kagan gegeben, die Sie akzeptieren sollten.
Vanadium
2
Verwenden Sie nicht echoin erster Linie: verwenden printf.
Chepner
2
Verwenden Sie immer einfache Anführungszeichen, wenn Sie sicherstellen möchten, dass genau das, was Sie schreiben, als Argument an den Befehl übergeben wird.
Giacomo Alzetta

Antworten:

29

Schrägstriche sind speziell durch behandelt echo -e, aber zuerst werden sie manchmal speziell durch die Schale (die in diesem Fall behandelt bash), nach der Shell zitiert Regeln.

Das Argument echosieht eigentlich so aus Hello\\n. Weil Sie bestanden haben , -ean echo, es behandelt Backslash entkommt speziell und \\wird zu einem einzigen zusammengebrochen \. Das Finale nwird nicht geflüchtet, so dass es buchstäblich erscheint.

Der Grund dafür ist, dass echodie Shell vor und unabhängig von der eigentlichen Operation in einigen Kontexten speziell behandelt,\ in anderen jedoch nicht. Unquoted \Zeichen werden immer speziell behandelt, in einfachen Anführungszeichen \ werden nie speziell behandelt, aber die Behandlung von doppelten Anführungszeichen \ Zeichen, wie in dem Befehl , den Sie lief, ist subtiler und kompliziert.

Wenn die Shell in einem Befehl auf doppelt in Anführungszeichen gesetzten Text stößt "Hello\\\n", wird dieser \wie ein Escape-Zeichen behandelt, wenn er einem Zeichen vorangeht, das in Anführungszeichen eine besondere Bedeutung haben kann, und nicht anders .

  1. Weil \manchmal eine besondere Bedeutung im Innern ist "", hat eine , die einer \anderen unmittelbar vorausgeht, \den Effekt, diese Sekunde zu zitieren \. In doppelten Anführungszeichen werden also die ersten \\zusammengefasst \.
  2. Nach diesen ersten beiden \Zeichen folgt ein drittes \Zeichen, das von den ersten beiden nicht betroffen ist und einem vorangestellt ist n. Ist naber kein Zeichen, das in Anführungszeichen speziell behandelt wird, so wird das \davor in dieser Situation nicht speziell behandelt. So \nbleibt \n.

Der Effekt ist, dass in doppelten Anführungszeichen \\\ninterpretiert wird als \\n.

Wenn echo -eangezeigt wird \\n, entfernt der erste \die spezielle Bedeutung aus dem zweiten und echodruckt \nbuchstäblich für diesen Text.


Wenn es Ihr Ziel ist, Hellomit einer zusätzlichen Zeile ohne Backslashes zu drucken (die Frage war ursprünglich nicht eindeutig, und ich denke, es ist ein nützliches Beispiel), dann besteht eine Lösung darin, a zu entfernen \. Ausführen von echo -e "Hello\\n"Ausgaben Hellomit einem zusätzlichen Zeilenumbruch am Ende.

Eine bessere Lösung besteht darin, einfache Anführungszeichen zu verwenden und zu schreiben echo -e 'Hello\n'. Einfache Anführungszeichen sind die stärkste Form des Zitierens. Eine noch bessere Lösung ist in der Regel die Verwendung printfvon echo, was in diesem Fall wäre printf 'Hello\n\n'.

Wenn Sie Hello\den Backslash gefolgt von einem zusätzlichen Zeilenumbruch drucken möchten , ist der Ansatz mit doppelten Anführungszeichen möglich, aber umständlich. Um es herausfinden , Arbeit rückwärts: echo -eKonvertiten \\zu \und \nauf eine neue Zeile, und doppelklicken zitiert Konvertiten \\zu \, so dass Sie es mit sechs Schrägstriche tun können ( echo -e "Hello\\\\\\n"), da \\nverwandelt sich in \naufgrund eines umgekehrten Schrägstrich ein anderes zu entkommen. Sie können dies auch mit fünf tun, da doppelte Anführungszeichen beibehalten werden, \nwenn das \nicht maskiert wird.

Dies zeigt den Vorteil echo -eder einfachen Anführungszeichen : Fügen Sie einfach alles, was Sie wollen , in die einfachen Anführungszeichen ein ( echo -e 'Hello\\\n'). printfist auch gut hier. Eine Möglichkeit ist printf 'Hello\\\n\n'. Aber was printfwirklich glänzt, ist, dass Sie zusätzliche Argumente einfügen können. Sie können anstelle von verwenden printf '%s\n\n' 'Hello\', was das zweite Argument einfügt (wörtlich, Hello\weil einfache Anführungszeichen nichts ändern) %s.

Eliah Kagan
quelle