Echo Newline-Zeichen funktioniert nicht in Bash

13

Ich habe ein Bash-Skript, das viele echoAnweisungen enthält, und ich habe auch einen Alias echofür echo -ebeide in .bash_profileund .bashrc, damit neue Zeilen für eine Anweisung, wie sie echo 'Hello\nWorld'ausgegeben werden soll, richtig gedruckt werden

Hello
World

aber die Ausgabe, die ich bekomme, ist

Hello\nWorld

Ich habe sogar versucht, shopt -s expand_aliasesdas Skript zu verwenden, es hilft nicht

Ich führe mein Skript aus als bash /scripts/scriptnm.sh; Wenn ich es ausführe, bekomme . /scripts/scriptnm.shich die gewünschte Ausgabe ...

Bashuser
quelle
3
Aliasing echowie Sie wollen ist eine schlechte Praxis IMHO
Shellholic
1
Verwenden Sie doppelte Anführungszeichen, damit das \ n interpretiert wird. Einfache Anführungszeichen verhindern die Interpretation von \ n und einer Reihe anderer Dinge.
BillThor

Antworten:

16

Die gemischte Historie von echobedeutet, dass die Standardoperation von Shell zu Shell variiert. POSIX gibt an, dass das Ergebnis von echo"implementierungsdefiniert" ist, wenn das erste Argument ist -noder ein Argument einen Backslash enthält.

Es ist zuverlässiger zu verwenden printf(entweder als integrierter Befehl oder als externer Befehl), wenn das Verhalten genauer definiert ist: Der Backslash im C-Stil wird ausgeblendet und Formatspezifizierer werden in der Formatzeichenfolge (dem ersten Argument) unterstützt.

printf 'foo\nbar\n'
printf '%s\n%s\n' foo bar

Sie können die Erweiterung von Backslash - Escape - Sequenzen von steuern bash ‚s echointegrierten Befehl mit der xpg_echoShell - Option.

Setzen Sie es oben in einem Bash- Skript, damit echoBackslash-Escapezeichen automatisch erweitert werden, ohne dass -ezu jedem Echo-Befehl etwas hinzugefügt werden muss.

shopt -s xpg_echo
echo 'foo\nbar'
Chris Johnsen
quelle
shopt -s xpg_echo; Hat für mich gearbeitet.
Bashuser
6

Bei Verwendung bash myfile.shwird Bash im Batch-Modus in einem separaten Prozess ausgeführt und liest weder das Profil noch die RC-Datei.

Wenn Sie verwenden . myfile.sh, wird die Datei stammt von dem aktuellen Shell - Prozess (als wenn der Inhalt von Ihnen eingegeben wurde), deshalb sieht es Ihre derzeit Aliase definiert.

Im Allgemeinen ist es eine sehr schlechte Idee, Skripte zu schreiben, die von einer bestimmten Shell-Konfiguration abhängen, insbesondere von Aliasen, es sei denn, Sie definieren sie im Skript selbst. ( Verlassen Sie sich niemals auf Benutzer .bashrc, auch wenn es Ihre eigenen sind.)

user1686
quelle
5

Es wird empfohlen, printfalle neuen Skripte zu verwenden.

printf '%s\n%s\n' "Hello" "World"

printf '%s\n' "Hello\nWorld"
Bis auf weiteres angehalten.
quelle
+1 printf ist etwas komplizierter zu verwenden als Echo, aber es zahlt sich mehr als aus, um Inkonsistenzen von Echo zu vermeiden.
Gordon Davisson
1

Dies funktioniert gut im Terminal

#!/bin/bash
alias echo="echo -e"
echo "Hello\nWorld"

Speichern Sie in einer Datei und machen Sie sie ausführbar (chmod + x)

Führen Sie als ./Ihre_Datei aus

LaLeX
quelle
Führen Sie es als bash your_file aus und überprüfen Sie die Ausgabe.
Bashuser
Funktioniert wie erwartet
LaLeX
Das Echo "Hello \ nWorld" zeigt jedoch nicht die erwartete Ausgabe an. Da Echo bereits auf Echo -e ausgerichtet ist, sollte es aber das funktioniert nicht und das ist meine Frage
Bashuser
Da es eine schlechte Praxis ist, Alias-Echo zu verwenden (Programme, die davon abhängen, können fehlerhaft sein), sollten Sie den Alias ​​entfernen und ihn in Ihrem Skript nach Echo-Ende durch Echo -e ersetzen
LaLeX
Vielen Dank LaLex für Ihre Antworten. Gibt es eine Möglichkeit, mit dem Alias ​​das erwartete Ergebnis zu erzielen, obwohl dies keine gute Vorgehensweise ist
Bashuser