環境変数

提供: ArchWiki
2023年6月4日 (日) 06:15時点におけるAshMyzk (トーク | 投稿記録)による版 (→‎グローバル: 同期)
ナビゲーションに移動 検索に移動

関連記事

環境変数とは 1 つ以上のアプリケーションによって使用されるデータを含む名前付きオブジェクトです。簡単に言えば、名前と値がある変数です。環境変数の値としては、実行可能ファイルのファイルシステムにおける場所や使用するデフォルトのエディタ、システムロケールの設定などがあります。Linux に慣れてないユーザーは、環境変数で設定をするのは御しがたいと考えがちです。しかし、環境変数は、Linux で複数のアプリケーションとプロセスの間で設定を共有するためのシンプルな方法を提供してくれます。

ユーティリティ

coreutils パッケージには printenvenv というプログラムが含まれています。現在の環境変数とその値を一覧表示するには:

$ printenv
ノート: 環境変数の中にはユーザ個別のものも存在します。printenv の出力を非特権ユーザの場合と root ユーザの場合で比較して確認してください。

env ユーティリティを使うことで、環境変数を変更してコマンドを実行することができます。以下の例では、環境変数 EDITORvim に設定して xterm を起動します。以下のコマンドを実行しても、グローバルな EDITOR 変数には影響を与えません。

$ env EDITOR=vim xterm

シェルset(1p) 組み込みコマンドを使えば、シェルオプションの値を変更したり、位置のパラメータを設定したり、シェル変数の名前とその値を出力したりできます。

各プロセスはその環境変数を /proc/$PID/environ ファイルに保存しています。このファイルには、ヌル文字 (\x0) で区切られたキーと値のペアが含まれています。sed を使用すると、より読み易い形式で取得できます。例: sed 's:\x0:\n:g' /proc/$PID/environ

変数の定義

環境を不必要に汚染しないために、変数のスコープを制限するように努めるべきです。実際、グラフィカルセッションや systemd サービスでは、変数を有効にするために特定の場所で設定することが要求されます。環境変数のスコープは、それらが影響を与えるコンテキストに分けられます:

グローバル

シェルの初期化ファイルを使う

大半の Linux ディストリビューションは、あなたに /etc/profile 等のファイルに環境変数の追加・変更を行うよう指示します。また、/etc/locale.conf のような変数設定を含むパッケージ固有の設定ファイルがあることも覚えておいてください。環境変数の維持・管理は必ず行い、環境変数を含むことができる多数のファイルに注意を払うようにしてください。原則的に、あらゆるシェルスクリプトは環境変数の初期化に使うことができますが、以下のような UNIX の慣例に従い特定のファイルでのみ行われるべきです。

以下のファイルは、システムのグローバルな環境変数を定義するために使用できますが、それぞれに異なる制限があります:

  • /etc/environmentpam_env モジュールによって使用され、シェルに依存しないため、スクリプトやグロブ展開は使用できません。このファイルは、変数=値 という形式しか受け入れません。
  • /etc/profile は、ログインシェルのみに対して変数を初期化します。しかし、このファイルはスクリプト (例: /etc/profile.d/ 内にあるファイル) を実行し、すべての Bourne shell 互換シェルで使用することができます。
  • シェル固有の設定ファイル - シェルのグローバルな設定ファイルで、変数の初期化やスクリプトの実行を行います。例えば Bash#設定ファイル (例: ~/.bashrc)) や Zsh#スタートアップ/シャットダウン ファイル (例: ~/.zshrc) です。

以下の例では、複数のディレクトリ (例えば ~/bin~/scripts) をそれぞれのユーザーの PATH に追加する関数を作成しています。これを行うには、以下を任意のグローバル環境変数の設定ファイル (/etc/profile または /etc/bash.bashrc) に記述するだけです:

set_path(){

    # ユーザ ID が 1000 以上であるか確認する
    [ "$(id -u)" -ge 1000 ] || return

    for i in "$@";
    do
        # ディレクトリが存在するか確認する
        [ -d "$i" ] || continue

        # ディレクトリが $PATH に既に存在するか確認する
        echo "$PATH" | grep -Eq "(^|:)$i(:|$)" && continue

        # ディレクトリを $PATH の末尾に追加し、export する
        export PATH="${PATH}:$i"
    done
}

set_path ~/bin ~/scripts

異なるシェル間で環境変数を共有する1つの方法として、envsubst によって直接読み込むことのできるファイルを、コメント、空行、スペース (bash) を含めずに、作成するというものがあります ([1] から着想を得ました):

.env
EDITOR=vim
XDG_CACHE_HOME=$HOME/.cache
XDG_CONFIG_HOME=$HOME/.config
XDG_DATA_HOME=$HOME/.local/share
XDG_STATE_HOME=$HOME/.local/state
bashrc
export $(envsubst < .env)
config/fish/config.fish
export (envsubst < .env)

pam_env を使う

pam_env(8) PAM モジュールは、環境に設定する変数を次のファイルから順番に読み込みます: /etc/security/pam_env.conf/etc/environment

ノート:
  • これらのファイルは、他のファイル、特に、~/.profile~/.bash_profile~/.zshenv より前に読み込まれます。
  • 非推奨の ~/.pam_environment はもう読み込まれません。FS#68945 を参照してください。

/etc/environment では、変数= というペアを1行に1つずつ記述しなければなりません。例:

EDITOR=nano

/etc/security/pam_env.conf は以下の形式で記述します:

VARIABLE [DEFAULT=value] [OVERRIDE=value]

@{HOME} @{SHELL} は、/etc/passwd で定義されているものに拡張される特別な変数です。次の例は、HOME 環境変数を別の変数に展開する方法を示しています:

XDG_CONFIG_HOME   DEFAULT=@{HOME}/.config
ノート: 変数 ${HOME} および ${SHELL} は、HOME および SHELL 環境変数にはリンクされていません。これらはデフォルトでは設定されていません。

また、この形式では、${VARIABLE} を使って、既に定義されている変数を他の変数の値で展開することができます。例えば:

GOPATH DEFAULT=${XDG_DATA_HOME}/go

VARIABLE=value のペアも可能ですが、これらのペアでは変数の展開はサポートされていません。詳しくは pam_env.conf(5) を参照してください。

ユーザーごと

環境変数をグローバルに定義したくないという時もあるでしょう。例えば、PATH/home/my_user/bin を追加したいが、システム上の他のユーザーには同じ PATH を使って欲しくないという場合が考えられます。様々なファイルを使うことでローカルに環境変数を定義することができます:

ローカルで PATH にディレクトリを追加したい場合、以下のように ~/.bash_profile に記述します:

export PATH="${PATH}:/home/my_user/bin"

変数をアップデートするために、再ログインするかファイルを source してください: $ source ~/.bash_profile

ノート: dbus デーモンや systemd のユーザーインスタンスは .bashrc などで設定された環境変数を継承しません。そのため、D-Bus によって Nautilus などのアプリケーションが起動した場合、デフォルトで設定された環境変数を使いません。Systemd/ユーザー#環境変数を参照してください。

グラフィック環境

環境変数がグラフィカルなアプリケーションにしか影響しない場合は、グラフィカルセッション内でのみ設定することにより、その範囲を制限することができます。スコープの降順:

デスクトップ環境セッションごと

いくつかのグラフィカルな環境 (例えば KDE Plasma) はログイン時にシェルスクリプトを実行することをサポートしており、環境変数の設定に利用することができます。KDE#自動起動 を参照してください。

Xorg セッションごと

Xorg セッションの環境を変更する手順は、Xorg セッションの起動方法によって異なります。

スクリプトの終わりはどのファイルであるかに依存し、高度な構文は使用するシェルに依存しますが、基本的な使い方は普遍的です。

~/.xprofile, ~/.xinitrc, or ~/.xsession
...
export GUI_VAR=value
...
Wayland セッションごと

Wayland は Xorg 関連のファイルを起動しないので、GDMKDE Plasma が代わりに systemd/ユーザーの環境変数 をソースとしています。

~/.config/environment.d/envvars.conf
GUI_VAR=value

Wayland セッションをサポートする他のディスプレイマネージャ(SDDM など)ではまだこのサポートを提供していません。

アプリケーションごと

セッション全体ではなく、特定のアプリケーションにのみ環境変数を設定するには、そのアプリケーションの .desktop ファイルを編集してください。その方法は デスクトップエントリ#環境変数の変更 を参照してください。

Steam ゲームでは、起動オプションを編集することでプログラムの環境を設定することができます。Steam#起動オプションを参照してください。

セッションごと

時としてもっと限られた定義が必要になる場面もあります。絶対パスを入力せずに指定したディレクトリから一時的に実行ファイルを起動したい場合や、アプリケーションを実行するために短時間だけ ~/.bash_profile を編集しなくてはならない場合などです。

その場合、export コマンドを使うことで、現在のセッションのみで PATH 変数を定義することができます。ログアウトするまでは、PATH 変数は一時的な設定が使われます。PATH に特定のディレクトリを追加するには、次を実行:

$ export PATH="${PATH}:/home/my_user/tmp/usr/bin"

以下のセクションでは Linux システムで一般的に使われている環境変数を並べており、それぞれの値について説明しています。

  • DE は使用中のデスクトップ環境 (desktop environment) を示すレガシー変数です。どのような値を取りうるかについての中心的なドキュメントはありませんが、xdg-utils は多くのデスクトップ環境についてのリファレンスを提供しています。
  • DESKTOP_SESSION もレガシーな変数です。DE に似ていますが、より一般的ではありません。セッションの (/usr/share/xsessions/ 内の) デスクトップエントリへのパスを格納できます [5]
  • WINDOW_MANAGER は、デスクトップ環境で使用するウィンドウマネージャ選択するために時々使われる変数です。他のプログラムが読み取るために、既に選択されているディスプレイマネージャやデスクトップ環境によって設定される他の変数とは対照的です。
  • PATH には、コロンで区切られたディレクトリのリストが格納されています。システムは、この変数に登録されているディレクトリから実行ファイルを探索します。通常のコマンド (例: lssystemctlpacman) がシェル (bashzsh など) によって解釈される際、シェルは PATH のリスト内のディレクトリからそのコマンドと同じ名前の実行ファイルを探索し、それを実行します。PATH に含まれないディレクトリにある実行ファイルを実行するには、実行ファイルへの相対パスや絶対パスを指定する必要があります。例えば、./a.out/bin/ls です。
ノート: セキュリティ上の理由により PATH にはカレント作業ディレクトリ (.) を含めないことが推奨されます。ユーザが騙されて、悪意のあるコマンドを実行してしまうかもしれないからです。
  • HOME には現在のユーザのホームディレクトリへのパスが格納されます。この変数は、アプリケーションが現在のユーザに関連した設定ファイル等を見つけるために使うことができます。
  • OLDPWD には前のワーキングディレクトリへのパスが入ります。つまり最後に cd を実行する前の PWD です。
  • TERM には、実行中のターミナル (terminal) の種類が格納されます (例: xterm-256color)。この変数は、ターミナル固有の機能を期待する、ターミナル内で実行されるプログラムによって使用されます。
  • MAIL には、受信したメールの保存場所が入ります。伝統的な設定は /var/spool/mail/$LOGNAME です。
  • ftp_proxyhttp_proxy にはそれぞれ FTP と HTTP プロキシサーバーを記述します:
ftp_proxy="ftp://192.168.0.1:21"
http_proxy="http://192.168.0.1:80"
  • MANPATH には、man が man ページを探索するディレクトリのリストがコンマで区切られて格納されます。
ノート: /etc/profile に "Man is much better than us at figuring this out" (man は我々よりずっと上手くこれを解決する) と書いてあるとおり、一般的にこの変数はデフォルトのままにしておくべきです。 manpath(5) を参照。
  • INFODIR には、info コマンドが info ページを探索するディレクトリのリストがコンマで区切られて格納されます。例: /usr/share/info:/usr/local/share/info
  • TZ は、ユーザ毎にシステムのタイムゾーンとは異なるタイムゾーンを設定するために使用することができます。/usr/share/zoneinfo/ 内にはタイムゾーンが列挙されているので、これをリファレンスとして使用することができます (例: TZ=":/usr/share/zoneinfo/Pacific/Fiji")。変数 TZ に zoneinfo ファイルを指定する場合、GNU マニュアル に従ってコロンで始める必要があります。

デフォルトプログラム

  • SHELL にはユーザの優先シェルへのパスが含まれます。この変数の値は、現在実行中のシェルである必要はないことに注意してください。この変数に値がない場合、Bash は自動的に /etc/passwd で定義されているユーザのログインシェルに設定するか、判断できない場合は /bin/sh にします。
  • PAGER には、ファイルの内容を一覧表示するために使用されるプログラムを実行するコマンドが含まれます。例: /bin/less
  • EDITOR には、ファイルの編集に使用される軽量プログラムを実行するコマンドが含まれています (例:/usr/bin/nano)。例えば、以下の例のように、X 下では gedit を使い、それ以外では nano を使うように設定するインタラクティブスイッチを記述することができます:
[ -n "$DISPLAY" ] && export EDITOR=gedit || export EDITOR=nano
  • VISUAL には、メールの編集などより高度な作業に使われる本格的なエディタを実行するコマンドが含まれています (例: vivimemacs など)。
  • BROWSER にはウェブブラウザへのパスが含まれています。グラフィカル環境 (X など) が利用できるかに応じてこの変数を動的に変更するようなコードをインタラクティブシェルの設定ファイルに記述しておくと便利です:
[ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
ヒント: WAYLAND_DISPLAY 環境変数を使うことで、Wayland コンポジタが実行されているかどうかに応じてこれらのデフォルトプログラムを設定することができます。

参照