【シェル】ヒアドキュメントのEOFの前にスペースは入れてはいけない

みたいです。

これはちょっとハマりました。

ヒアドキュメントとは

ヒアドキュメントという機能を知っていますでしょうか?

簡単に言えば複数行で文字列を表示させる機能です。


Qiitaで探すといっぱいでてきます。
詳しい機能は下記など、いろいろ探してみてください。
qiita.com


ざっくり使い方

コマンドは下記のように使えます。

$ cat << EOF
> aaa
> bbb
> ccc
> EOF
aaa
bbb
ccc

シェルスクリプト

もちろん同じようにシェルスクリプトで使うこともできます。

eof_test.sh

cat << EOF
aaa
  bbb
ccc
  ddd
EOF

でなにが問題か?

functionで使ってみる

function内で使おうとすると、下記のようにインデントを入れて使いたくなります。

eof_test.sh

function hoge() {
  cat << EOF
  hoge
  EOF
}
hoge

でこれを実行するとエラーになります。

eof_test.sh: 行 7: 警告: ヒアドキュメントの 3 行目でファイル終了 (EOF) に達しました (`EOF' が必要)
eof_test.sh: 行 8: 構文エラー: 予期しないファイル終了 (EOF) です

なのでEOFがある行の行頭スペースを除けばOKです。

function hoge() {
  cat << EOF
#cat << EOF ←この行も行頭スペースなしにしてもいい
  hoge
EOF  # ←この行頭スペースを省く
}
hoge

これがzshで実行すると…?

でここが核心なのですが、たまたまこのようなスクリプトzshで実行してたんですね。
zshで実行するとエラーログがこんなのでます。

eof_test.zsh:7: parse error near `\n'

なんのエラーなのかわからない!!!(ToT;;)


shで実行した場合はこんな風にでます。

eof_test.sh: 行 7: 警告: ヒアドキュメントの 3 行目でファイル終了 (EOF) に達しました (`EOF' が必要)
eof_test.sh: 行 8: 構文エラー: 予期しないファイル終了 (EOF) です

なので、あーEOF付近のエラーだなと推測がつくのですが
zshは全然どこが悪いのか推測がつかなかったので
かなり時間を浪費しました。


しかもエラーが出た時は数百行のスクリプトのかなり上の方にEOFを書いてて
エラー指摘の行が一番最後だったので、エラー原因を探るのにかなり苦労しました…。



このことが誰かの役に立ちますように。。。



入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

新しいシェルプログラミングの教科書

新しいシェルプログラミングの教科書