シェルスクリプトを作成する際、複数行にわたるメッセージの出力や設定ファイルの生成を効率化したい場面は非常に多くあります。
そのような時に強力な武器となるのが、Bashの「ヒアドキュメント(Here Document)」という機能です。
ヒアドキュメントを活用することで、コマンドに対して直接複数行のテキストを流し込むことが可能になり、コードの可読性を劇的に向上させることができます。
本記事では、初心者の方から実務でスクリプトを記述するエンジニアの方まで役立つよう、ヒアドキュメントの基本から応用的なテクニックまでを詳しく解説します。
Bashのヒアドキュメントとは
ヒアドキュメントとは、シェルスクリプト内でコマンドへの標準入力として、複数行の文字列を直接記述するための構文です。
通常、複数行の文字列を扱う場合はechoコマンドを何度も繰り返したり、外部ファイルを読み込んだりする必要がありますが、ヒアドキュメントを使えばその必要はありません。
基本的に<<という記号に続けて「終了識別子」を指定することで、その識別子が再び現れるまでの区間をテキストとして扱います。
スクリプトの保守性を高めるために欠かせない高度なリダイレクト手法の一つと言えるでしょう。
基本的な構文
ヒアドキュメントの最もシンプルな記述方法は、以下のような構造になります。
command << EOF
ここに流し込みたい
テキストを記述します
EOF
ここで使用しているEOF(End Of File)は終了を知らせるためのラベルであり、任意の文字列を使用することが可能です。
ヒアドキュメントの基本的な使い方
まずは最も一般的な、標準出力への複数行表示を行ってみましょう。
catコマンドと組み合わせることで、指定した文字列をそのまま画面に表示させることができます。
cat << LIMITER
これはサンプルのテキストです。
改行もそのまま反映されます。
LIMITER
上記のスクリプトを実行すると、ターミナルには以下のように表示されます。
これはサンプルのテキストです。
改行もそのまま反映されます。
このように、特別なエスケープシーケンスを使わずに改行を表現できる点が大きなメリットです。
変数展開の制御とクォートの使い分け
ヒアドキュメント内では、デフォルトでシェル変数の展開が行われます。
しかし、場合によってはシェル変数を展開せずに、記号そのままを出力したいケースもあります。
変数を展開する場合
以下の例では、変数USER_NAMEの値がヒアドキュメント内で展開されます。
USER_NAME="Alice"
cat << EOF
こんにちは、${USER_NAME}さん。
現在の時刻は $(date) です。
EOF
こんにちは、Aliceさん。
現在の時刻は 2026年 5月 20日 水曜日 12:00:00 JST です。
このように、スクリプト内で動的に変化する値を埋め込む際に非常に便利です。
変数の展開を無効化する場合
一方で、スクリプト内で$記号をそのまま表示させたい場合や、設定ファイルを生成する際に変数展開をさせたくない場合があります。
そのときは、開始時の識別子を引用符(シングルクォートやダブルクォート)で囲みます。
USER_NAME="Alice"
cat << 'EOF'
こんにちは、${USER_NAME}さん。
この部分は展開されません。
EOF
こんにちは、${USER_NAME}さん。
この部分は展開されません。
識別子を'EOF'のように囲むだけで、ヒアドキュメント全体がリテラルとして扱われるようになります。
タブやインデントの削除(<<- 演算子)
シェルスクリプトを記述する際、if文やfor文の中でヒアドキュメントを使うと、インデントの関係でコードが見づらくなることがあります。
通常の<<を使用すると、行頭の空白やタブもそのままデータとして処理されてしまうためです。
これを解決するために、Bashには<<-という演算子が用意されています。
<<-を使用すると、各行の先頭にある「タブ文字」を自動的に削除してくれます。
<<- の使用例
以下のスクリプトを見てみましょう。
if true; then
cat <<- EOF
この行の先頭にはタブが入っています。
出力時にはこのタブが削除されます。
EOF
fi
この場合、出力結果では行頭のタブが無視され、左詰めで表示されます。
注意点として、削除されるのはタブ文字のみであり、半角スペースによるインデントは削除されません。
モダンなエディタでは自動的にスペースに変換される設定(ソフトタブ)が多いため、この機能を使う際は注意が必要です。
ヒアドキュメントをファイルへ保存する
ヒアドキュメントは画面に表示するだけでなく、設定ファイルやテンプレートファイルを生成するのにも適しています。
リダイレクト演算子>や>>と組み合わせることで、簡単にファイルへの書き出しが行えます。
cat << EOF > config.txt
db_name=production_db
db_user=admin
db_password=secret
EOF
このコマンドを実行すると、config.txtというファイルが作成され、指定した3行の内容が書き込まれます。
既存のファイルに追記したい場合は、>>を使用してください。
パイプラインとの組み合わせ
ヒアドキュメントの出力を、別のコマンドへパイプで渡すことも可能です。
例えば、入力したテキストの中から特定の文字列を検索したり、並び替えたりする場合に有効です。
cat << EOF | grep "重要"
これは通常のメッセージです。
これは重要な通知です。
EOF
この例では、「重要な通知です」という行のみが抽出されます。
ヒアドキュメント内でコマンドを実行する
ヒアドキュメントの内部では、コマンド置換($(command))を利用してコマンドの実行結果を埋め込むことができます。
レポートの作成や、システムのステータスを出力するスクリプトなどでよく利用されるテクニックです。
cat << EOF
サーバー稼働状況報告
Hostname: $(hostname)
Current Load: $(uptime | awk '{print $10}')
EOF
これにより、実行時の最新状況を反映させたメッセージを手軽に作成できます。
ヒアドキュメントの活用パターン一覧
主な使い方と特徴を以下の表にまとめました。
| 演算子 | 主な特徴 | 主な用途 |
|---|---|---|
<< EOF | 変数を展開する標準的な形式 | メッセージ出力、動的ファイル生成 |
<< 'EOF' | 変数を展開しない(リテラル) | ソースコードの出力、設定ファイルの雛形 |
<<- EOF | 行頭のタブを無視する | インデントされたスクリプト内の整理 |
<<< "STRING" | ヒアストリング(単一行向け) | 短い文字列をコマンドへ渡す |
ヒアドキュメントの注意点とベストプラクティス
ヒアドキュメントを安全に使用するために、いくつかの注意点を理解しておきましょう。
終了識別子の独立性
終了識別子(例:EOF)は、必ずその行の先頭に記述し、その行には識別子以外を含めないようにしてください。
識別子の前後にスペースが入っているだけで、Bashは終了地点として認識してくれず、エラーの原因となります。
識別子の名前選び
一般的にEOFが使われますが、内容に合わせてSQL、CONFIG、MESSAGEなどの分かりやすい名前を付けることが推奨されます。
コードを読み返す際に、何のためのデータブロックなのかが一目で判断できるようになります。
SSH越しのコマンド実行
リモートサーバーに対してSSH経由で複数のコマンドを実行したい場合、ヒアドキュメントをSSHコマンドに渡す手法が非常に便利です。
ssh user@remote-host << 'EOF'
cd /var/www/html
ls -al
df -h
EOF
これにより、リモート側での一連の作業をローカルスクリプトから一括で制御できます。
このとき、変数の展開をローカルで行うかリモートで行うかに応じて、クォートの有無を適切に選択するようにしましょう。
まとめ
Bashのヒアドキュメントは、複雑な文字列操作をシンプルにし、スクリプトのメンテナンス性を向上させるための非常に優れた機能です。
改行をそのまま扱える基本的な使い方から、'EOF'による変数展開の抑制、<<-によるインデント制御まで、状況に応じた使い分けが重要となります。
本記事で紹介したテクニックを駆使して、より見やすく、より強力なシェルスクリプトの作成に役立ててください。
特に設定ファイルの自動生成やリモートメンテナンスにおいては、ヒアドキュメントの習熟度が作業効率を大きく左右することでしょう。
