なんか<<EOF
とかやると複数行の文字列をスクリプト内に埋め込めるやつ、という認識である。
最近、terraformでヒアドキュメントを使って複数行にわたる文字列をパラメータや変数に渡すことが多い。これを機に調べる。
- 概要
- スクリプトごとの実装
このあたりを理解したい。
概要を理解したい
ヒアドキュメントの厳密な定義や宣言があって、それをもとに各言語で実装されているものだと思い込んでいたが、どうやら違うらしいことが分かってきた。
一次情報に近そうなドキュメントを探したが見つからなかった。 個人ブログかwikipedia、あるいは世界の辞書的なサイトになろうとしているページしか見つからない。 あまり自明な概念ではないと思う。みんなが勝手に合意をしているものなのだろう。
https://en.wikipedia.org/wiki/Here_document この手の話題には珍しくwikipediaを参照させてもらう。それくらい、参考ドキュメントの発掘に困っている。
「あたかも別ファイルかのように扱える、ソースコード内の一部」だそうだ。 まあ単純に「複数行の文字列入力ができる書き方」という理解であまり間違ってなさそうに思える。
Unixシェルが起源であるという記述が複数見つかるが、信用にたるドキュメントは見つからない。
言語ごとの使われ方を知りたい
bash
https://www.gnu.org/software/bash/manual/bash.html#Here-Documents
The format of here-documents is:
[n]<<[-]word here-document delimiter
最初のword
をクオートすると、here-document部分の変数が展開されないそうだ。へぇ。
他の言語でもおおむね同じっぽい。jsでは同じような概念でテンプレートリテラルがES6から導入されている。 jsに慣れている私としては、最初から「テンプレートリテラルみたいなものだよ」って説明してくれればスッと理解できたのに...。
終端識別子、自由過ぎない?
<<EOF
のEOF
部分を何て呼ぶかが分からなかったのでChat GPTに聞いた。呼び方があっているのかは分からない。
スクリプト内で一意であればよいらしいが、あまりにも自由すぎやしないだろうか...。この自由さが、最初の理解を阻んでいた気がする。
人によってEOF
やEOL
やEOT
にしているのを見る。"Enf Of File"とかそういうところから来ているのだろう。
終端識別子が自由な理由は考えてみれば明快だった。 終端識別子自体をヒアドキュメントに含められないからだ。
エスケープすればいいじゃんとなるが、特定文字だけエスケープが必要だと、「スクリプト内であたかも別ファイルかのように扱う」のニュアンスが薄れてしまうだろう。