簡単なスクリプトや設定ファイルなど、環境変数を埋め込んたファイルを生成したいみたいなパターンのときにenvsubstコマンドが使えます
今まで知らなかったことがもったいない
ということでメモ残しておきます
インストール
gettextを入れると使えるようになる
- yum
yum install -y gettext
- apt
apt install -y gettext
help
envsubst --help
Usage: envsubst [OPTION] [SHELL-FORMAT]
Substitutes the values of environment variables.
Operation mode:
-v, --variables output the variables occurring in SHELL-FORMAT
Informative output:
-h, --help display this help and exit
-V, --version output version information and exit
In normal operation mode, standard input is copied to standard output,
with references to environment variables of the form $VARIABLE or ${VARIABLE}
being replaced with the corresponding values. If a SHELL-FORMAT is given,
only those environment variables that are referenced in SHELL-FORMAT are
substituted; otherwise all environment variables references occurring in
standard input are substituted.
When --variables is used, standard input is ignored, and the output consists
of the environment variables that are referenced in SHELL-FORMAT, one per line.
Report bugs to <bug-gnu-gettext@gnu.org>.
標準入力から$VARIABLEまたは${VARIABLE}という形式で参照される環境変数を読み込んで、対応する値に置き換えてから標準出力に出力します
echo '$USER' | envsubst vagrant
$ cat config.template.yml name: $USER $ cat config.template.yml | envsubst name: vagrant
リダイレクトすれば環境変数を含めたファイルを生成できますね
変数展開対象を指定する
たとえばJavaScriptだとテンプレートリテラルでの変数参照方法とかぶっているので意図せず空文字にされてしまうパターンがある
- 試してみる
$ cat hoge.js
const directory = '$PWD';
const user = '$USER';
console.log(`${user}ユーザーで${directory}にいます`);
$ cat hoge.js | envsubst const directory = '/home/vagrant/dotfiles'; const user = 'vagrant'; console.log(`ユーザーでにいます`);
${user}と${directory}という環境変数がないため空白として処理されてしまっています
SHELL-FORMAT
こういう場合ヘルプにもあるように[SHELL-FORMAT]を指定してあげることで特定の環境変数のみ埋め込みます
展開対象の変数名をenvsubstコマンドの後に記述します
$ cat hoge.js | envsubst '$USER $PWD'
const directory = '/home/vagrant/dotfiles';
const user = 'vagrant';
console.log(`${user}ユーザーで${directory}にいます`);
複数ある場合は列挙するなりスペースで区切るなりすることで実現できるが第一引数という扱いらしいのでシングルクオートで囲ってあげる必要はあります
区切りのスペースはありでもなしでも問題なく埋め込んでくれます
これで求めている変換結果が返ってきました
- 実行してみる
サンプルなので標準出力からそのまま実行してみます
$ cat hoge.js | envsubst '$USER$PWD' | node vagrantユーザーで/home/vagrant/dotfilesにいます
バッチリですね
対象の確認
-vオプションで変換対象の変数を確認できます
$ envsubst --variables '$HOGE some text ${FUGA}'
HOGE
FUGA
ファイルの中身を渡せば対象の変数となる値を確認できますね
-vで複数行の指定は出来ないため1行に変換してやってみます
$ cat hoge.js
const directory = '$PWD';
const user = '$USER';
console.log(`${user}ユーザーで${directory}にいます`);
$ envsubst -v "$(cat hoge.js | sed -z 's/\n/ /g')" PWD USER user directory
$PWDと$USERのみ変換対象としたかいがuserとdirectoryも対象として入ってしまっていますね
意図した文字列以外も対象に入ってしまうのでSHELL-FORMATの指定が必要そうです
おわり
ブックマークレットを作っていたところAPIキーが必要になりキーはGit管理化には置けないけど貼り付けるときは埋め込んでおきたいといった用途でした
他にも簡単なスクリプトや設定ファイルなどにも使えそうなので覚えておきます