web-dev-qa-db-ja.com

ヒアドキュメントで「予期しないファイルの終わり」エラーが発生する

端末からメールを送信するにはスクリプトが必要です。私がここで見たものや他の多くのオンラインの場所に基づいて、次のようにフォーマットしました。

/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

ただし、これを実行すると、次の警告が表示されます。

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

...ここで、行xはプログラムで最後に記述されたコード行であり、行yは/var/mailが含まれる行です。 EOFを他のもの(ENDOFMESSAGEFINISHなど)に置き換えようとしましたが、役に立ちませんでした。私がオンラインで見つけたほぼすべてのものがこの方法で行われ、bashは本当に新しいので、自分でそれを理解するのに苦労しています。誰も助けを提供できますか?

57
thnkwthprtls

EOFトークンは行の先頭にある必要があり、コードブロックと共にインデントすることはできません。

<<-EOFと書くとインデントできますが、インデントする必要があります Tab スペースではなく文字。そのため、コードのブロックがあっても、最終的には終了しない可能性があります。

また、空白がないことを確認してくださいafter行のEOFトークン。

120
Barmar

Here-docを開始または終了する行には、おそらくいくつかの非印刷可能文字または空白文字(キャリッジリターンなど)があります。つまり、2番目の "EOF"は最初と一致せず、here-docそうすべき。これは非常に一般的なエラーであり、テキストエディターだけでは検出が困難です。たとえばcatを使用すると、印刷できない文字を表示できます。

cat -A myfile.sh

cat -Aからの出力が表示されたら、解決策は明らかです。問題のある文字を削除してください。

10
Joni

EOF:の前にある前のスペースを削除してください:-

/var/mail -s "$SUBJECT" "$EMAIL" <<-EOF

Identに<tab>の代わりに<spaces>を使用し、<-EOFを使用すると正常に機能します。

"-"<tabs>ではなく<spaces>を削除しますが、少なくともこれは機能します。

5
Rahul Tripathi

これを行うと、このエラーが発生する可能性があります。

while read line; do
  echo $line
done << somefile

この場合、<< somefile< somefileを読み取る必要があるためです。

0