envsubstコマンドでシェル変数を環境変数で展開する方法|テンプレートファイルの動的生成と実務活用も

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, シェルスクリプト > envsubstコマンドでシェル変数を環境変数で展開する方法|テンプレートファイルの動的生成と実務活用も
「設定ファイルをサーバーごとに手書きで変えるのが面倒だ。」
「Dockerfileや nginx.conf のIPアドレス・ドメインをまとめて差し替えたい。」

こういった悩みを抱えているなら、envsubst コマンドがそのまま解決策になります。
envsubst は環境変数をテンプレート文字列に埋め込むだけのシンプルなコマンドですが、
設定ファイルの動的生成・CI/CD パイプライン・Docker エントリーポイントと組み合わせると
驚くほどの作業を自動化できます。

この記事では、envsubst コマンドの基本から実務でよく使うパターンまで
RHEL 9.4 / Ubuntu 24.04 LTS の実機で確認した手順で解説します。

この記事のポイント

・envsubst はテンプレートの $VAR を環境変数で一括置換するコマンド
・置換対象変数を限定する書き方で誤置換を防げる
・nginx.conf や Docker エントリーポイントとの組み合わせが実務の定番
・変数が未定義の場合は空文字に展開される点に注意


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

envsubst とは何か・なぜ使うのか

envsubst は GNU gettext パッケージに含まれる小さなコマンドです。
標準入力またはファイルを読み込み、$変数名${変数名} の形式を
対応する環境変数の値に置き換えて標準出力に書き出します。

「それなら sed でもできるのでは?」と思うかもしれません。
sed でも実現できますが、変数名が増えるほど sed の -e オプションが増えてコマンドが複雑になります。
envsubst は環境変数をそのまま使うため、変数をセットするだけで自動的にテンプレートへ反映されます。

特に以下の場面で真価を発揮します。

・同じ nginx.conf をステージング環境と本番環境で使い回す
・Docker コンテナ起動時に設定ファイルを動的に生成する(エントリーポイントスクリプト)
・CI/CD パイプラインでサービスごとに異なるドメイン・ポートを埋め込む
・シェルスクリプトからメールや通知のテンプレートを生成する

インストール確認と基本構文

1. envsubst がインストール済みか確認する

RHEL / CentOS 系では gettext パッケージに含まれています。
Ubuntu / Debian 系では gettext-base パッケージです。

# インストール確認 which envsubst # 出力例 /usr/bin/envsubst # バージョン確認 envsubst --version # 出力例 envsubst (GNU gettext-runtime) 0.21 Copyright (C) 2003-2020 Free Software Foundation, Inc.

コマンドが見つからない場合はパッケージをインストールしてください。

# RHEL / Rocky Linux / AlmaLinux sudo dnf install gettext -y # Ubuntu / Debian sudo apt install gettext-base -y

2. 基本的な使い方(ヒアドキュメント)

最も手軽な使い方はヒアドキュメントと組み合わせる方法です。

# 環境変数をセット export SERVER_NAME=web01.example.com export LISTEN_PORT=8080 # テンプレートをヒアドキュメントで渡す envsubst << 'EOF' server { listen $LISTEN_PORT; server_name $SERVER_NAME; } EOF # 出力例 server { listen 8080; server_name web01.example.com; }

3. ファイルを入力にして別ファイルへ出力する

実務ではテンプレートファイルを事前に用意しておき、
envsubst でデプロイ用の設定ファイルを生成するパターンが多いです。

# テンプレートファイルを作成 cat nginx.conf.template server { listen $LISTEN_PORT; server_name $SERVER_NAME; root /var/www/$APP_NAME; } # 環境変数をセットして展開・出力 export SERVER_NAME=prod.example.com export LISTEN_PORT=443 export APP_NAME=myapp envsubst < nginx.conf.template > /etc/nginx/conf.d/myapp.conf # 生成されたファイルを確認 cat /etc/nginx/conf.d/myapp.conf server { listen 443; server_name prod.example.com; root /var/www/myapp; }

置換する変数を限定する(誤置換防止)

1. なぜ変数の限定が必要か

nginx.conf のような設定ファイルには、シェル変数に見えるが
nginx 固有の変数(例:$uri$host$request_uri)が含まれることがあります。
envsubst をそのまま使うと、これらも展開対象になって空文字に置き換わる危険があります。

# 危険な例($uri が空文字に展開される) cat nginx.conf.template location / { proxy_pass http://$BACKEND_HOST; return 301 https://$host$uri; # nginx 固有変数 } export BACKEND_HOST=app.internal envsubst < nginx.conf.template # 出力($uri が消える) location / { proxy_pass http://app.internal; return 301 https://; # $host も $uri も消えた }

2. 第2引数で置換対象変数を限定する

envsubst の第2引数(シングルクォートで囲んだ変数名リスト)を指定すると、
そのリストに含まれる変数だけを展開し、それ以外はそのまま残します。

# BACKEND_HOST だけを展開する($host・$uri はそのまま残る) export BACKEND_HOST=app.internal envsubst '$BACKEND_HOST' < nginx.conf.template > /etc/nginx/conf.d/proxy.conf # 確認 cat /etc/nginx/conf.d/proxy.conf location / { proxy_pass http://app.internal; return 301 https://$host$uri; # nginx 固有変数は保持される }

複数変数を限定する場合はスペース区切りで並べます。

# 複数変数を限定指定 envsubst '$SERVER_NAME $LISTEN_PORT $APP_NAME' < nginx.conf.template > /etc/nginx/conf.d/myapp.conf

実務での活用パターン

1. Docker エントリーポイントスクリプトでの設定生成

Docker コンテナを起動するとき、環境変数で挙動を変えたい場面は非常に多くあります。
entrypoint.sh で envsubst を呼び出すパターンが実務の定番です。

# entrypoint.sh の例 #!/bin/bash set -e # テンプレートから実際の設定ファイルを生成 envsubst '$SERVER_NAME $LISTEN_PORT' \ < /etc/nginx/templates/default.conf.template \ > /etc/nginx/conf.d/default.conf # nginx を起動 exec nginx -g 'daemon off;'

コンテナ起動時に -e SERVER_NAME=prod.example.com -e LISTEN_PORT=80 を渡すだけで
設定ファイルが自動生成される仕組みです。
nginx の公式 Docker イメージはこのパターンを公式に採用しています。

2. シェルスクリプトで通知メールを動的生成する

バックアップスクリプトや監視スクリプトから送信するメールのテンプレートを
envsubst で動的に生成することも実務でよく使います。

# メールテンプレートファイル(mail.template) Subject: [$ENV] バックアップ完了通知 To: $ADMIN_EMAIL $HOSTNAME のバックアップが完了しました。 実行時刻: $TIMESTAMP バックアップ先: $BACKUP_PATH

# バックアップスクリプト内での使用例 export ENV=production export ADMIN_EMAIL=ops@example.com export HOSTNAME=$(hostname) export TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') export BACKUP_PATH=/backup/$(date '+%Y%m%d') envsubst < mail.template | sendmail -t

3. Ansible・CI/CD パイプラインとの連携

GitHub Actions や GitLab CI でも envsubst はよく使われます。
リポジトリにはテンプレートだけをコミットしておき、
シークレット変数を環境変数として渡してデプロイ時に実体ファイルを生成するパターンです。

# .github/workflows/deploy.yml の抜粋例 - name: Generate config from template env: DB_HOST: ${{ secrets.DB_HOST }} DB_NAME: ${{ secrets.DB_NAME }} APP_SECRET: ${{ secrets.APP_SECRET }} run: | envsubst '$DB_HOST $DB_NAME $APP_SECRET' \ < config/app.conf.template \ > config/app.conf

テンプレートをバージョン管理しつつ、機密情報をシークレットで保持できるため
セキュリティと保守性を両立できます。

トラブルシュート・よくある問題と対処

1. 変数が展開されずそのままになる

最も多いのは変数が export されていないケースです。
envsubst はシェルの 環境変数(export 済み)しか参照しません。

# NG(ローカル変数のため展開されない) MY_VAR=hello echo '$MY_VAR' | envsubst # 出力: $MY_VAR(展開されない) # OK(export すれば展開される) export MY_VAR=hello echo '$MY_VAR' | envsubst # 出力: hello

2. 変数名が空文字に展開されてしまう

環境変数が未定義のまま envsubst を実行すると、
$変数名 は空文字列に展開されます。
誤って必要な変数を消してしまわないよう、実行前に変数が定義されているか確認しましょう。

# 実行前の変数確認スクリプト(必須チェック) required_vars=(SERVER_NAME LISTEN_PORT APP_NAME) for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then echo "Error: 環境変数 $var が未定義です" >&2 exit 1 fi done # チェック通過後に envsubst を実行 envsubst '$SERVER_NAME $LISTEN_PORT $APP_NAME' \ < nginx.conf.template > /etc/nginx/conf.d/myapp.conf

3. シングルクォートとダブルクォートの混同

第2引数(変数名リスト)は シングルクォート で囲む必要があります。
ダブルクォートにするとシェルが展開してしまい、意図と異なる動作になります。

export SERVER_NAME=prod.example.com # NG(ダブルクォートはシェルが $SERVER_NAME を展開する) envsubst "$SERVER_NAME" < template.conf > output.conf # 第2引数が "prod.example.com" になるため変数名として認識されない # OK(シングルクォートで変数名をそのまま渡す) envsubst '$SERVER_NAME' < template.conf > output.conf

4. テンプレート内の $ をそのまま残したい場合

テンプレートに envsubst で展開させたくない $ 記号が含まれる場合は、
第2引数で置換変数を明示的に限定するか、$$ とエスケープします。

# $$ はリテラルの $ に展開される cat template.txt 価格は $$1,000 です。サーバー: $SERVER_NAME export SERVER_NAME=web01.example.com envsubst '$SERVER_NAME' < template.txt # 出力($SERVER_NAME のみ展開、$$ はリテラル $ に変換) 価格は $1,000 です。サーバー: web01.example.com

本記事のまとめ

やりたいこと コマンド
ヒアドキュメントで変数展開する envsubst << 'EOF' ... EOF
テンプレートファイルを展開して出力 envsubst < template.conf > output.conf
特定の変数だけ展開する(誤置換防止) envsubst '$VAR1 $VAR2' < template.conf
インストール(RHEL系) sudo dnf install gettext -y
インストール(Ubuntu/Debian系) sudo apt install gettext-base -y
変数が定義済みか確認してから実行 [ -z "${VAR}" ] && exit 1 の後に envsubst
envsubst は「環境変数をテンプレートに埋め込む」というシンプルな機能だけを持つコマンドですが、
その単純さこそが強みです。
nginx の公式 Docker イメージが採用しているように、
設定ファイルの動的生成において最もシンプルで信頼性の高い手段のひとつです。

置換対象変数を限定する第2引数をきちんと使えば、
nginx 固有変数や他のツール固有の $変数 を誤って消してしまうリスクも排除できます。

Linux ポート確認の全コマンド
Apache タイムアウト設定の詳細 と組み合わせて、
Linuxサーバーの設定管理を自動化する一歩を踏み出してみてください。

envsubstで設定ファイルの動的生成を身につけたら、次はサーバー全体の構築スキルを体系的に固めませんか?

envsubstによるテンプレート展開はサーバー運用自動化の基礎の一つです。シェルスクリプト・ネットワーク設定・ファイアウォールと合わせて体系的に身につけることで、現場で頼られるエンジニアになれます。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として15年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。