作業ノート

様々なまとめ、雑感など

bashのヒアドキュメントを使ったスクリプトの作成

仕事で行った作業を社内のwikiなどにまとめるとき、その作業で実行したコマンドを含めてまとめている。

最近ではスクリプトの作成手順を示す際に、catコマンドを使って

$ cat <<EOT > foo.sh
#!/bin/bash
set -eu

...

EOT

このように表記している。

これはbashのヒアドキュメントを利用したもので、これをコピペして実行するだけで必要なスクリプトが作成できるので、とても便利。

ただ、この記述ではドキュメント内にbashで解釈可能な変数があると、その変数が展開されてしまう。

例えば

$ cat <<EOT > foo.sh
#!/bin/bash
set -eu

PATH=$PATH:/path/to/bin
EOT

このようにして作成したスクリプトを確認すると

$ cat foo.sh
#!/bin/bash
set -eu

PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/X11/bin:/usr/X11R6/bin:/path/to/bin

変数($PATH)が展開されてしまう。

これを回避する方法の一つは、ヒアドキュメントのワード(最初のEOT)をクォートで囲む。

囲むのは単一引用符(')でも

$ cat <<'EOT' > foo-sq.sh
#!/bin/bash
set -eu

PATH=$PATH:/path/to/bin
EOT

$ cat foo-sq.sh
#!/bin/bash
set -eu

PATH=$PATH:/path/to/bin

二重引用符(")でも同じで

$ cat <<"EOT" > foo-dq.sh
#!/bin/bash
set -eu

PATH=$PATH:/path/to/bin
EOT

$ cat foo-dq.sh
#!/bin/bash
set -eu

PATH=$PATH:/path/to/bin

どちらもヒアドキュメント全体で、変数は展開されない。

別の方法としては、$をエスケープする(\)と、エスケープしたところは展開されない。

$ cat <<EOT > foo-es.sh
#!/bin/bash
set -eu

PATH=\$PATH:/path/to/bin
EOT

$ cat foo-es.sh
#!/bin/bash
set -eu

PATH=$PATH:/path/to/bin

変数の展開を限定的にしたい場合は、こちらを利用する。

参考