Linux / コマンド / printenv - 環境変数の値を表示

printenvは、現在のプロセス環境にある変数の値を出力するGNU Coreutilsのコマンドです。変数名を指定すると必要な値だけを確認でき、名前を省略するとすべての環境変数を出力します。

環境を変更してコマンドを実行するenvとは異なり、printenvは参照に集中します。シェル変数と環境変数の違いをチェックしたり、スクリプトで変数が渡されているかどうかを確認する際に便利です。

printenvコマンドとは?

プログラムは親プロセスから環境変数のセットを受け取ります。printenvは、自分に渡された環境から全体の項目または指定した名前の値を標準出力に出力します。

シェル内部のみに存在しexportされていない変数は環境に含まれないため、printenvでは見えません。

基本的な文法

printenv [オプション] [変数 ...]

変数名なしで実行すると、すべての環境変数を名前=値形式で出力します。

printenv
printenv | sort

全体の環境には認証トークンやサービス接続情報が含まれる場合があります。結果を共有したりログに保存する前に、機密情報が含まれていないか確認してください。

特定の環境変数を確認する

printenv HOME
printenv PATH
printenv LANG

変数名を指定すると値だけを出力し、名前=の接頭辞は付けません。複数の名前も一度に指定できます。

printenv HOME SHELL USER

出力だけでは各行がどの変数に対応しているか判別しにくい場合があるため、人が読むレポートであれば名前を別に表示する方法も検討してください。

変数が存在するか終了ステータスで確認する

GNU printenvは指定した変数をすべて見つけた場合は0、ひとつでも見つけられなかった場合は1を返します。書き込みエラーが発生した場合は2を返します。

if printenv APP_ENV >/dev/null; then
  printf '%s\n' 'APP_ENV is exported'
else
  printf '%s\n' 'APP_ENV is not exported'
fi

この if の例は成功と失敗だけを分けています。厳密に判定する場合は、存在しない場合の状態 1 と書き込みエラーの状態 2 を区別し、エラーを「export されていない」と断定しないでください。値が空文字列の環境変数も「存在する変数」です。値が空かどうかと変数が存在しないかどうかを区別するには、終了ステータスと出力を一緒に確認する必要があります。

シェル変数はあるがprintenvに表示されない場合

この例は APP_MODE がまだ環境へエクスポートされていない状態を前提にします。既に export 済みの変数は、値を代入し直してもその属性が残ります。練習では bash --noprofile --norc で別の Bash を開き、unset -v APP_MODE を実行してから以下を試します。終了後に exit で元のシェルへ戻れば、元の変数設定を変えずに確認できます。

APP_MODE=development
printf '%s\n' "$APP_MODE"
printenv APP_MODE

最初の代入はBashのシェル変数を作りますが、子プロセス環境にエクスポートはされません。printenvは外部プログラムなので、その値を受け取ることはできません。

export APP_MODE
printenv APP_MODE

exportの後には、以降に実行されるprintenvや他の子プロセスはその値を受け取ることができます。

PATH項目を一行ずつ表示する

PATHはコロンで区切られたディレクトリの一覧なので、次のように読みやすく分けることができます。

printenv PATH | tr ':' '\n'

空の項目は現在のディレクトリを意味する場合があり、セキュリティ上の問題になることがあります。出力で最初、最後、または連続するコロンがあるかも確認してください。

NUL(値が0の文字)で区切る -0

printenv -0
printenv --null

-0または--nullは各項目の末尾に改行の代わりにNUL文字を出力します。環境変数の値自体に改行が含まれる可能性があるため、他のプログラムが結果を曖昧さなく処理する場合に便利です。

printenv -0 | while IFS= read -r -d '' item; do
  printf '%q\n' "$item"
done

この例でのread -dの使い方はBashを基準としています。単純なテキストツールはNUL区切りの入力をサポートしない場合があるため、パイプライン全体がその形式を処理できるか確認してください。

サポートオプション

オプション 説明
-0, --null 各出力項目の末尾を改行の代わりにNUL文字にします。
--help 使用法を表示して終了します。
--version プログラムのバージョンを表示して終了します。

-0はGNU Coreutilsの機能です。他のUnix系システムではサポート状況が異なる場合があります。

printenv・env・printfの比較

コマンド 確認対象 特徴
printenv NAME 子プロセスに渡された環境変数 特定の環境変数の存在有無を終了ステータスで確認するのに便利です。
env 現在の環境全体 環境を変更して別のコマンドを実行する機能が核心です。
printf '%s\n' "$NAME" 現在のシェルが展開した変数の値 環境にエクスポートされていないシェル変数も表示できます。

echo "$NAME"でも値を見ることができますが、オプションのように見える値やバックスラッシュ処理の実装の違いを避けるには、スクリプトではprintfの方が予測可能です。

一時的に設定した環境を確認する

変数の追加・削除や空の環境からの起動は、env の環境設定とコマンド実行で詳しく説明しています。

envと一緒に使うと、特定のコマンドに渡される値を確認できます。

env APP_ENV=staging printenv APP_ENV
env -u HTTP_PROXY printenv HTTP_PROXY

2番目のコマンドは変数が削除されたので、何も出力せず失敗状態を返します。

プロセスごとに値が異なる理由

環境はシステム全体の単一の表ではなく、各プロセスが持つデータです。新しいターミナル、SSHセッション、systemdサービス、cronジョブ、コンテナはそれぞれ異なる親プロセスと起動設定を使用するため、同じ変数名でも値が異なるか、存在しない場合があります。

問題を診断する際は、実際にプログラムが実行されるのと同じユーザー・サービス・コンテナ環境でprintenvを実行する必要があります。ターミナルで表示される値がサービスにも自動的に渡されると仮定してはいけません。

環境変数出力時のセキュリティ注意事項

  • 全てのprintenvの結果を公開イシューやチャットに貼り付けないでください。
  • 継続的インテグレーション(CI、Continuous Integration)のログでトークンやパスワードがマスキングされているか確認します。
  • 必要な変数名だけを指定して、最小限の値だけを参照します。
  • 秘密値が必要か確認するときは、値を出力せずに終了状態を使用します。
  • 環境変数は同じ権限のデバッグツールや子プロセスに露出する可能性があるため、秘密保管庫自体としては扱いません。

よく発生する問題

値を設定したのに出力されない場合があります。

シェル変数だけを作って export はしていない可能性が高いです。export 名前 を実行した後、新しい子プロセスで確認してください。

空行が出力されたのですが、変数がないということですか?

変数が空文字列に設定されている場合と存在しない場合は、画面だけでは区別が難しいことがあります。コマンドの終了状態を確認してください。

printenv EMPTY_VALUE
printf 'status=%s\n' "$?"

sudo の後では環境変数が消えます。

sudo はセキュリティポリシーにより環境変数を削除または制限します。無条件に保存する方法で回避するのではなく、sudoers ポリシーと対象コマンドに必要な変数だけを確認してください。

よくある質問

printenv は現在のシェルのすべての変数を表示しますか?

いいえ。環境にエクスポートされた変数のみを表示します。Bash のローカル変数、配列、一部の特殊変数は declare や set のようなシェル組み込みコマンドで確認する必要があります。

特定の変数の名前と値を一緒に出力できますか?

printenv NAMEは値だけを出力します。名前まで必要な場合はprintf 'NAME=%s\n' "$(printenv NAME)"のように構成できますが、コマンド置換は末尾の改行を削除するため、元の値をそのまま保持する作業には注意が必要です。

printenvで環境変数を変更できますか?

いいえ。printenvは参照コマンドです。現在のシェルでは代入とexportを使用し、1つのコマンドだけに適用する場合はenv 名前=値 コマンドを使用してください。

参考資料