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
変数の展開を限定的にしたい場合は、こちらを利用する。