690
580

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

bashのヒアドキュメントを活用する

Last updated at Posted at 2014-11-19

ヒアドキュメントとは

複数行の文字列を簡潔に記述するための機能です。

これを

echo 'hoge'
echo 'fuga'
echo 'piyo'

こんな風に記述できます

cat << EOS
hoge
fuga
piyo
EOS

ヒアドキュメントはシェルスクリプトの中にちょっとした別のスクリプトを埋め込むときに便利です。
数行のスクリプトのためにわざわざファイルを作る必要がなくなり、見通しがよくなります。

# ちょっとしたスクリプトを動かすのに便利
# 例) oracleDBのテーブル一覧を出力する
sqlplus -S user/pass@sid << EOS
set pagesize 0
set feedback off

select table_name from tabs
order by table_name;
EOS

要点

ヒアドキュメントを理解するうえで重要なのは、ヒアドキュメントは標準入力として扱われる、ということです。
文字列リテラルでないことに注意してください。

これを把握していれば、最初の例でcatにヒアドキュメントを渡していた理由がわかるかと思います。
catはファイルを省略した場合に標準入力から読むため、ヒアドキュメントの内容が標準出力に出ることになります。

逆に下記のようにechoに渡しても内容が標準出力に出ることはありません。echoは標準入力から読まないし、
ヒアドキュメントはリテラルではないからです。

# 改行が出力されて終わり
echo << EOS
hoge
fuga
EOS

文法

コマンドに<< EOSが渡されると次の行からEOSが単独で現れる行までの間が
ヒアドキュメントの内容になります。

言い換えれば、コマンドそのものが記載された行に、コマンドの振る舞いを指定し、
そこで標準入力として与える内容を次の行から記載することになります。

EOSの部分は任意の文字を使うことができます。HOGEでも_DOC_でも問題ありません。
「EOSが単独で現れる行」というのは空白やタブなど、一切のほかの文字も含んではいけません。

「次の行から」というのもポイントです。
つまりは以下のようにも書けます。

# ヒアドキュメントの内容とmyfile.txtの内容を連結してconcat.txtに書き込む
cat - << EOS myfile.txt > concat.txt
hoge
fuga
EOS

なおここで、catの直後-は、catの仕様として、ファイル名を指定すると標準入力から読み込まなくなるため、
明示的に-を指定して、標準入力として渡したい箇所を指定する必要があります。

変数展開・コマンド置換

ヒアドキュメントの中でも""で括った文字列リテラルと同様、
変数展開やコマンド置換が行われます。

つまり$MY_VAR$(date)と書くといつもと同じように展開されます。

これを抑止する(=''で括ったときのように扱う)にはEOSの部分を下記のようにクォートします。

cat << 'EOS'
    $MY_VAR と書いても展開されない
EOS

行頭のタブを取り除く

ヒアドキュメントは便利ですが、インデントできないのが難点です。
EOSをインデントしてしまうとヒアドキュメントの終わりとして認識してくれませんし、
ヒアドキュメントの内容にインデントがそのまま反映されてしまいます。

この問題を解決するための機能が用意されていて、<<<<-に書き換えるだけで
使用できます。<<-でヒアドキュメントを書くと、行頭のタブを無視してくれます。

ただし、タブといっているのはハードタブのみでスペースは相変わらず取り除いてくれません。
(たぶんヒアドキュメント中でインデントするときのためにこうしていると思うのですが・・・)

# >--- はハードタブだと思って読んでください
cat <<- EOS
>---    hoge
>---        fuga
>---EOS

上記の例は

    hoge
        fuga

と表示されます。

変数に代入する

ヒアドキュメントは標準入力なので、変数に入れるにはちょっとした細工が必要です。
以下のようにすれば変数に代入することができます。

HOGE=$(cat << EOS
hoge
fuga
EOS
)

# もしくは
HOGE=`cat << EOS
hoge
fuga
EOS
`
690
580
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
690
580

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?