Linuxで環境変数の一覧を表示・活用する方法

Linux の「環境変数一覧」を調べるときは、値を画面やログへ全部流さないことが第一です。環境には API トークン、プロキシ認証、クラウド資格情報、セッション情報が入ることがあります。まず必要な変数名を決めて個別に確認し、全体調査が必要なら名前だけを NUL 区切りで抽出します。ここでは Bash と GNU coreutils を基準に、シェル変数、export 済み環境、別プロセスの /proc 表示を区別します。 確認ポイント:環境変数の全値dumpはtokenなどの秘密情報を漏らすため、確認対象の名前を限定します。

目次

export前後をprintenvとdeclareで見分ける

printenv は現在のプロセスが受け取っている環境を表示します。引数なしは全項目、名前を与えるとその値だけです。指定名が存在すれば終了値 0、存在しない名前が一つでもあれば非 0 になります。env も引数なしなら環境を表示しますが、主用途は環境を追加・削除・空にしてコマンドを起動することです。declare -x は Bash 組み込みで、export 属性を持つ変数をシェル形式で列挙します。値は引用された形になり得るため、env の NAME=value と同じ出力形式だとは考えません。

DEMO_COLOR=blue
printf 'shell=<%s>\n' "$DEMO_COLOR"
printenv DEMO_COLOR; printf 'printenv rc=%d\n' "$?"
declare -p DEMO_COLOR
export DEMO_COLOR
printenv DEMO_COLOR
declare -x DEMO_COLOR

期待出力は、最初が shell=<blue>、export 前の printenv は何も表示せず printenv rc=1、declare -p は declare -- DEMO_COLOR="blue" です。export 後は printenv が blue、declare -x が declare -x DEMO_COLOR="blue" を出します。つまり name=value だけではシェル変数であり、子プロセスへ渡すには export name または export name=value が必要です。

一つの値を安全に確認する

値が必要なら printenv -- NAME を使うと、名前がハイフンで始まる場合のオプション解釈を止められます。ただし通常の環境変数名は英字またはアンダースコアで始まる識別子に限定するのが移植しやすい設計です。シェル内の値を参照する printf '%s\n' "$NAME" は shell 展開なので、未 export の変数も見えます。echo $NAME は未引用展開、glob 展開、-n 解釈などが絡むため診断には使いません。

if printenv -- HOME >/dev/null; then
  printf 'HOME is exported; length=%d\n' "${#HOME}"
else
  printf 'HOME is not exported\n' >&2
fi
printf 'PATH entries=%d\n' "$(printf '%s' "$PATH" | awk -F: '{print NF}')"

この例は HOME や PATH の実値を出さず、存在と文字数・要素数だけを表示します。HOME が export 済みなら例として HOME is exported; length=11 のように出ますが、長さは利用者名で変わります。秘密候補は printenv TOKEN で表示せず、printenv TOKEN >/dev/null の終了値だけ確認します。空文字でも「存在する」ので、非空も必要なら Bash で [[ -n ${TOKEN+x} && -n $TOKEN ]] と分けて判定します。

一覧は値を出さず、変数名だけにする

GNU の env -0 または printenv -0 は各環境エントリを改行ではなく NUL で終端します。値には改行が入り得るため、通常の env | sed ... は名前一覧として壊れることがあります。GNU coreutils の NUL 対応オプションを組み合わせれば、値を端末へ露出せずに名前だけを並べられます。

env -0 | cut -z -d= -f1 | sort -z | tr '\0' '\n'
printf 'exported names=%s\n' "$(env -0 | grep -z -c '^[A-Za-z_][A-Za-z0-9_]*=')"

1行目の出力は HOME、LANG、PATH などの名前だけです。2行目は export 済み項目数を表示します。-0、-z は GNU 系の機能で、BusyBox や BSD の各実装では利用可否を env --help、cut --help で確認します。移植性を優先する監査では、全一覧を変形するより for name in HOME PATH LANG; do printenv "$name" >/dev/null && printf '%s\n' "$name"; done のように許可リストだけを確認します。

declare -x や export -p は値も出すため、画面共有、CI ログ、チケット添付にはそのまま貼りません。「伏字化」を行うなら入力を NUL で扱い、名前だけ残すか、必要な許可リスト項目に限定します。単純な sed 's/=.*/=REDACTED/' は値中の改行より後ろを漏らす可能性があります。

プロセスごとの範囲を再現する

環境はプロセスごとに保持され、親から新しい子へコピーされます。子が値を変更しても、既に動作している親へ逆流しません。コマンドの直前に代入を書くと、そのコマンドだけへ値を渡せます。env -u NAME command は一項目を除外し、env -i command は空の環境から起動します。ただし PATH や locale が消えるので、検証対象コマンドを絶対パスで指定します。

export DEMO_SCOPE=parent
DEMO_SCOPE=one-command bash -c 'printf "child1=%s\n" "$DEMO_SCOPE"'
bash -c 'DEMO_SCOPE=child; export DEMO_SCOPE; printf "child2=%s\n" "$DEMO_SCOPE"'
printf 'parent=%s\n' "$DEMO_SCOPE"
env -u DEMO_SCOPE bash -c 'printf "removed=<%s>\n" "${DEMO_SCOPE-unset}"'

正確な出力は child1=one-command、child2=child、parent=parent、removed=<unset> です。最後にこの説明用変数を現在の Bash から除くなら unset DEMO_SCOPE とします。永続設定ファイルは変更していないため、ファイルのロールバックは不要です。

/proc/$PID/environ を読む条件

Linux の /proc/PID/environ は、対象プログラムの初期環境を NUL 区切りで公開する擬似ファイルです。通常のテキスト行ではないため cat で端末へ出すと読みにくく、秘密値も漏れます。アクセスは ptrace の資格情報検査を受け、別ユーザー、権限を落としたプロセス、hidepid 付き procfs、コンテナ境界などでは同じ管理者の想定でも拒否されることがあります。読めない場合に権限やマウント設定を緩めず、対象プロセス自身で許可リスト項目を報告させる方法を選びます。

env PROC_DEMO=visible bash -c '
  tr "\0" "\n" </proc/$$/environ | grep -x "PROC_DEMO=visible"
  printf "reader_rc=%d pid=%s\n" "$?" "$$"
'

Linux の procfs へ同一プロセスからアクセスできれば、出力は PROC_DEMO=visible と reader_rc=0 pid=数値 です。NUL を改行へ変換してから、既知の非秘密項目へ完全一致しています。/proc/$$/environ は Bash 起動後に追加した shell 変数のライブ一覧ではありません。環境領域はプログラムが書き換えたり移動したりできるため、現在のアプリ状態を保証する API として扱わず、起動時診断の補助に限定します。

失敗条件と確認

  • printenv NAME が 1: 未設定または未 export。declare -p NAME と比較して区別する。
  • /proc/PID/environ が Permission denied: 他プロセスの秘密を読むために権限を広げず、所有者・名前空間・procfs 設定を確認する。
  • 一覧件数が期待より少ない: systemd、cron、SSH、コンテナなど起動元が異なれば環境も異なる。実際のサービスプロセス内で確認する。
  • 値に改行がある: 改行区切りの一覧解析をやめ、NUL 対応ツールか許可リスト照会を使う。
  • 調査ログへ値が残った: ログ共有を止め、該当資格情報を必要に応じて失効し、名前のみの再採取へ切り替える。

公式情報・参考資料

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次