Ich benötige mein Skript, um eine E-Mail vom Terminal zu senden. Basierend auf dem, was ich hier und an vielen anderen Orten online gesehen habe, habe ich es so formatiert:
/var/mail -s "$SUBJECT" "$EMAIL" << EOF
Here's a line of my message!
And here's another line!
Last line of the message here!
EOF
Wenn ich dies ausführe, erhalte ich jedoch folgende Warnung:
myfile.sh: line x: warning: here-document at line y delimited by end-of-file (wanted 'EOF')
myfile.sh: line x+1: syntax error: unexpected end of file
... wobei Zeile x die letzte geschriebene Codezeile im Programm ist und Zeile y die Zeile mit dem Code ist /var/mail
. Ich habe versucht , zu ersetzen EOF
mit anderen Dingen ( ENDOFMESSAGE
, FINISH
usw.) , aber ohne Erfolg. Fast alles, was ich online gefunden habe, hat es auf diese Weise gemacht, und ich bin wirklich neu bei Bash, daher fällt es mir schwer, es selbst herauszufinden. Könnte jemand Hilfe anbieten?
EOF
Linie eingerückt? Es muss am Anfang der Zeile stehen.<<-EOF
- gnu.org/software/bash/manual/bashref.html#Here-DocumentsAntworten:
Das
EOF
Token muss sich am Anfang der Zeile befinden. Sie können es nicht zusammen mit dem dazugehörigen Codeblock einrücken.Wenn Sie schreiben
<<-EOF
, können Sie es einrücken, aber es muss mit TabZeichen und nicht mit Leerzeichen eingerückt werden. Es könnte also auch mit dem Codeblock nicht enden.Stellen Sie außerdem sicher, dass nach dem
EOF
Token in der Zeile kein Leerzeichen steht .quelle
dos2unix
beheben Sie diese.Die Zeile, die das Here-Doc beginnt oder beendet, enthält wahrscheinlich einige nicht druckbare Zeichen oder Leerzeichen (z. B. Wagenrücklauf), was bedeutet, dass das zweite "EOF" nicht mit dem ersten übereinstimmt und das Here-Doc nicht wie endet es sollte. Dies ist ein sehr häufiger Fehler, der nur mit einem Texteditor schwer zu erkennen ist. Sie können nicht druckbare Zeichen sichtbar machen, zum Beispiel mit
cat
:Sobald Sie die Ausgabe
cat -A
der Lösung sehen, ist dies offensichtlich: Entfernen Sie die fehlerhaften Zeichen.quelle
Bitte versuchen Sie, die vorhergehenden Leerzeichen zu entfernen, bevor Sie
EOF
: -/var/mail -s "$SUBJECT" "$EMAIL" <<-EOF
Die Verwendung
<tab>
anstelle von<spaces>
für ident UND die Verwendung von << - EOF funktioniert einwandfrei.Das
"-"
entfernt das<tabs>
nicht<spaces>
, aber zumindest funktioniert das.quelle
Beachten Sie, dass dieser Fehler auch auftreten kann, wenn Sie dies tun.
while read line; do echo $line done << somefile
Da
<< somefile
sollte< somefile
in diesem Fall gelesen werden.quelle
Hier ist eine flexible Möglichkeit, mit mehreren eingerückten Zeilen umzugehen, ohne heredoc zu verwenden.
echo 'Hello!' sed -e 's:^\s*::' < <(echo ' Some indented text here. Some indented text here. ') if [[ true ]]; then sed -e 's:^\s\{4,4\}::' < <(echo ' Some indented text here. Some extra indented text here. Some indented text here. ') fi
Einige Hinweise zu dieser Lösung:
\
mit Anführungszeichen oder durch doppelte Anführungszeichen ersetzen. Achten Sie im letzteren Fall darauf, dass die Konstruktion wie$(command)
interpretiert wird. Wenn die Zeichenfolge sowohl einfache als auch doppelte Anführungszeichen enthält, müssen Sie zumindest der Art entkommen.quelle
Wenn ich Docstrings für meine Bash-Funktionen haben möchte , verwende ich eine Lösung ähnlich dem Vorschlag von user12205 in einem Duplikat dieser Frage.
Sehen Sie, wie ich USAGE für eine Lösung definiere, die:
function foo { # Docstring read -r -d '' USAGE <<' END' # This method prints foo to the terminal. # # Enter `foo -h` to see the docstring. # It has indentations and multiple lines. # # Change the delimiter if you need hashtag for some reason. # This can include $$ and = and eval, but won't be evaluated END if [ "$1" = "-h" ] then echo "$USAGE" | cut -d "#" -f 2 | cut -c 2- return fi echo "foo" }
So
foo -h
ergibt sich:This method prints foo to the terminal. Enter `foo -h` to see the docstring. It has indentations and multiple lines. Change the delimiter if you need hashtag for some reason. This can include $$ and = and eval, but won't be evaluated
Erläuterung
cut -d "#" -f 2
: Rufen Sie den zweiten Teil der#
abgegrenzten Zeilen ab. (Denken Sie an eine CSV mit "#" als Trennzeichen, leere erste Spalte).cut -c 2-
: Rufen Sie das 2. bis Endzeichen der resultierenden Zeichenfolge abBeachten Sie auch, dass dies so
if [ "$1" = "-h" ]
ausgewertet wird, alsFalse
gäbe es kein erstes Argument ohne Fehler, da es sich um eine leere Zeichenfolge handelt.quelle
Zusammen mit den anderen Antworten von Barmar und Joni ist mir aufgefallen, dass ich bei der Verwendung manchmal vor und nach meinem EOF eine leere Zeile hinterlassen muss
<<-EOF
.quelle
cat
und aufgrund der Formatierung musste ich kurz vor dem Schließen des Here-Doc-Markers vor dem schließenden Paren eine Eingabe hinzufügen, sonst würde ich diese Nichtübereinstimmung erhalten. Upvoting als vollständig gültig für "einige" Leute da draußen, wenn auch wahrscheinlich ein unwahrscheinliches Szenario.