printenvで見える環境変数はどこから来るのか

printenvで見える環境変数はどこかにテキストとして保存されてるのかな?
はじめに
Linuxで printenv を実行すると、多数の環境変数が表示されます。
printenv
一見すると「これらはどこかの設定ファイルに保存されているのでは?」と思いがちですが、それは誤解です。
この記事では、
- 環境変数の正体
- なぜ1つのファイルに存在しないのか
- どこから注入されているのか
を整理して解説します。
結論(最重要)
printenv に表示される環境変数は、 どこか1つのファイルに保存されているわけではありません。
👉 OS・認証・systemd・bash設定ファイルなどが 起動時に順番に注入した結果が、 現在の bash プロセスのメモリ上に存在している だけです。
環境変数の大原則
環境変数はファイルではなく、プロセスの属性である
- 環境変数は「今動いているプロセス」に紐づく
- プロセスが終了すれば消える
printenvは「現在の bash プロセス」を覗いている
環境変数はどうやって作られるのか
bash が起動するまでに、以下の流れで環境変数が作られます。
OS / カーネル
↓
ログイン処理(login / sshd)
↓
PAM(認証・ロケール)
↓
systemd(ユーザーセッション)
↓
bash 設定ファイル
↓
現在の bash プロセス(printenv)
出どころ別に見る環境変数
① ログイン処理・OS由来(ファイルに保存されない)
例:
USER
LOGNAME
HOME
SHELL
PWD
SHLVL
_
/etc/passwdを元に生成- login / sshd が設定
- 対応する設定ファイルは存在しない
② PAM(認証・ロケール)由来
例:
LANG
TEXTDOMAIN
MOTD_SHOWN
主な設定元:
/etc/default/locale/etc/pam.d/login/etc/pam.d/sshd
👉 cat --help が日本語になる原因はここ
③ systemd / XDG 系
例:
XDG_RUNTIME_DIR
XDG_SESSION_ID
XDG_SESSION_TYPE
DBUS_SESSION_BUS_ADDRESS
- systemd がユーザーセッション開始時に設定
/run/user/UID/配下で管理- 再起動すると消える
④ bash の設定ファイル由来
例:
PATH
LS_COLORS
設定元:
/etc/profile/etc/profile.d/*.sh~/.bash_profile~/.bashrc
例:
exportPATH=…
eval “$(dircolors)”
⑤ SSH 接続由来
例:
SSH_CONNECTION
SSH_CLIENT
SSH_TTY
- sshd が接続時に自動設定
- ファイル保存なし
なぜ「保存されているように見える」のか
再ログイン後も同じ環境変数が見える理由は:
毎回、同じ設定ファイルや仕組みが 同じ変数を作り直しているから
環境変数が残っているのではなく、 毎回新しく生成されているだけです。
永続化の正しい考え方
❌ 環境変数を保存する
⭕ 環境変数を作るコマンドを書く
例:
exportLANG=ja_JP.UTF-8
を以下のいずれかに書く:
~/.bashrc~/.bash_profile/etc/profile
まとめ(1文)
printenvに表示される環境変数は設定ファイルではなく、 ログインから bash 起動までの「履歴の集大成」である
おわりに
この仕組みを理解すると、
- なぜ設定が分散しているのか
- なぜ export が一時的なのか
- なぜ再ログインで同じ環境になるのか
がすべて一本につながります。
Linux の「分かりにくさ」は、 実は一貫した設計思想の結果なのです。
