Shellスクリプト

【Shellスクリプト】複数行のテキスト出力!ヒアドキュメントについて!

2020年4月7日

シェルスクリプトで処理を行う際、複数行のテキストをファイルに出力し、それを読み込ませたいという場面が良くあります。そんな時、一行ずつechoを実行するよりもヒアドキュメントでの記述にすればすっきりと書けてコードの可読性を上げる事が出来ます。

ヒアドキュメントとは?

ヒアドキュメントは、コマンドの標準入力に一定の文書を入力する書式コマンドです。

一定の内容の文書を即席で作成して、これをコマンドの標準入力にリダイレクトしたいことが時々あります。そんな時、このヒアドキュメントは非常に便利です。

コマンドの書式

「コマンド」 <<[-] EOF・・・終了文字
<ヒアドキュメント本文>
EOF・・・終了文字

ヒアドキュメントでは、次の行の行頭から終了文字列(EOF)が現れる直前の行までをヒアドキュメント本文とし、その内容がコマンドの標準入力にリダイレクトされます。

「<<」の右側の終了文字列(EOF)がクォート「'」されている場合は、ヒアドキュメント本文の展開は行われず、変数を処理できません。

始まりの文字はEOF固定と言うわけではなく好きな文字を設定する事が可能ですが、「EOF(エンドオブファイル)」が一般的です。

標準入力へリダイレクト

下記の書式は、「'」で囲んだ場合のヒアドキュメントと「’」で囲まない場合のヒアドキュメントの2つのパターン記載しています。

str="あいうえお" 

# クォーテーションで囲んだヒアドキュメント
$ cat << 'EOF'
${str}     👈 変数
hoge
fuga
EOF

# クォーテーションで囲まないヒアドキュメント(変数展開)
$ cat << EOF
${str}    👈 変数
hoge
fuga
EOF

2つのパターンのヒアドキュメントを実行してみます。

クォーテーションで囲んだヒアドキュメントは変数展開を行いません。逆にクォーテーションで囲まないヒアドキュメントは変数展開を行っていることが分かります。

メモ

設定を行う対象が、1台2台なら設定ファイルを直接手書きで編集するのも良いのですが、実際のプロジェクトでは300台のサーバーを設定するなど普通にあります。ヒアドキュメントを習得することで、省力化を測ることができます!

ヒアドキュメントのインデント

ヒアドキュメントを扱う際に、必ず聞かれる質問第一位が「インデントが設定できない!」と言う問題です。タブを使ってインデントする場合、コマンドが正しく実行できません。

「<<」の直後に「-」を付けた場合、ヒアドキュメント本体の行頭のタブが無視されるようになります。重要なことは「終了文字列(EOF)」がタブでインデントされていることです。半角スペースでは無視されません。

# タブ:■
# 半角スペース:□

$ cat <<- EOF
□□${str}
□□hoge
□□fuga
■EOF 👈 「□□(半角スペース)」でインデントすると、エラーとなります。

ヒアドキュメントは非常に有用なコマンド書式と言う事が分かると思います。

echoコマンドとの違い

「ヒアドキュメント」以外でも、「echo」コマンドを使って標準出力することが可能です。

echoコマンド自体は引数として指定した文字列リテラル(=文字列としてみなされる定数)を「1行ずつ」出力するコマンドなので、改行したいときには少し工夫が要ります。

もっとも単純に考えれば、echoコマンドを順番に複数回実行すれば、1回のecho実行ごとに改行がされるため、目的は達成できますがやや「そうじゃない!」感が漂います。

$ echo hoge
$ echo fuga
$ echo doga

他の方法、例えばbashの場合echoコマンドでは"-eオプションを使用"し、"改行コードを引数に含めて、連続して各行の内容を入力する"ことで、改行をしながら入力する事が出来ます。

$ echo -e "hoge\nfuga\ndoga"

「echo」コマンドの実行結果

実行結果の出力が「hoge」「fuga」「doga」と3行に分かれて出力されています。

これは""(ダブルクォーテーション)の中に「\n」が含まれており、「\n」がbashでエスケープ文字として解釈されずに改行コードとして出力された事によります。

ちなみに今度は「""(ダブルクォーテーション)」が無い状態と「-e」オプションが無い状態で実行してみます。

# 「""(ダブルクォーテーション)」が無い状態
$ echo -e hoge\nfuga\ndoga

# 「-e」オプションが無い状態
$ echo "hoge\nfuga\ndoga"

このようにechoコマンドだけでも複数行のテキスト出力は出来ますが、多くの行を入力するときには不便かつ可読性も落ちます。

ココに注意

シェルの種類によっては、-eオプションは使用できないものもあるので、スクリプトを書くときの環境、シェルには注意してください。

ファイルへ出力する方法

ヒアドキュメントを使って、ファイルへ複数行のテキスト出力を行いたい場合はどうすればよいでしょうか?

これまでの例(上記)では、catは 入力元を明示しない場合は、標準入力から入力を受け付けるため、ヒアドキュメントは標準入力として扱われている事が分かります。

入力があれば出力先を指定するのがcatコマンドの文法のため、以下のようにファイルへリダイレクトする、という処理を記述すればファイルへ出力することが可能です。

下記にファイル出力する場合の記述をしてみます。

# ヒアドキュメントを使ってファイルへ出力する
$ cat << EOF > ./aaa.txt
hoge
fuga
EOF

「echo」コマンドの引数としてヒアドキュメントの書式を用いても同様の結果が出るように思われますが、echoコマンドは標準入力から読み込みを行わなず、引数の文字列リテラルのみを出力するため、今回のケースでは何も出力されません。

この特性をうまく使いこなせば、OSの設定ファイル等の面倒な設定が一発で、差し替え可能となります。

catコマンドを利用したヒアドキュメントの記述

catコマンドは標準入力を受け付けるため、ヒアドキュメントと組み合わせて使う事が多いですが、他にも様々な使い道があります。

例えば、ヒアドキュメントは標準入力として扱われる事からそのままでは変数として保存できません。

そんな時は、宣言した変数内へコマンド置換でcatコマンドを変数に設定し、その入力としてヒアドキュメントを記載するようにすれば目的を達成できます。

# 宣言した変数内へコマンド置換でcatコマンドを変数に設定
$ TEST=$(cat << EOF
hoge
fuga
EOF
)

まとめ

ヒアドキュメントの使い方について、説明してきました。ヒアドキュメントは、使い方によっては非常にパワフルで書式なコマンドとなります。

サーバーOSの設定ファイルから、スクリプトの外部ファイルの操作まで、ヒアドキュメントの存在はかなり重宝します。ヒアドキュメントを覚えておいて、損はありません! 積極的に覚えていきましょう!

よく読まれている記事

1

目次1 Shellとは?1.1 代表的なシェルの種類2 シェルスクリプトの違いとは? Shellとは? Shellとは、人間の理解できる言葉を機会へ伝えるプログラムです。 Linux環境でコマンドプロ ...

2

Linuxは主にサーバー用として利用されるOSです。大規模な基幹システムの開発者、ロボットや家電開発等の組み込み系エンジニア、ネットワーク機器やデータベースに携わるインフラエンジニアは触れることが多い ...

3

プログラミング言語を習得しようと思った時、必ずと言っていいほど候補として挙げられるのが「Java」というプログラミング言語です。 「Java」は、現在日本で最も使われている言語であり、非常に人気のある ...

4

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-Shellスクリプト

Copyright© Beエンジニア , 2020 All Rights Reserved.