環境變量

出自 Arch Linux 中文维基

環境變量是一個具名對象,包含可被一個或多個應用程序使用的數據。簡單來說,它是具有一對名稱和值的變量。環境變量的值可以是文件系統上所有可執行程序的位置,默認的編輯器,系統本地化設置等。Linux 新用戶可能覺得這種管理變量的方式有點混亂。但是環境變量提供了一種在多個程序和進程間共享配置的簡單方式。

工具[編輯 | 編輯原始碼]

coreutils 軟件包含程序 printenvenv . 要顯示當前環境變量的值:

$ printenv
注意: 一些環境變量是屬於特定用戶的. 比較一般用戶和 root 用戶的 printenv 就可以看到差異。

工具 env 可以用指定的環境變量執行一個命令。下面例子把環境變量 EDITOR 設置為 vim 然後執行命令 xterm. 這個操作不會影響全局環境變量 EDITOR.

$ env EDITOR=vim xterm

shell 內置的set(1p) 命令可以設置 shell 選項值以及位置參數,或顯示 shell 變量的名稱和值。

每個進程都把它們的環境變量保存在 /proc/$PID/environ 文件中。此文件包含用 nul (\x0) 字符分隔的鍵值對。用 sed 可以獲得用戶可讀的內容,如:sed 's:\x0:\n:g' /proc/$PID/environ.

定義變量[編輯 | 編輯原始碼]

為了避免過多的環境設置,應該限制變量的作用域。圖形會話和 systemd 服務要求在明確的位置設置環境變量。變量的作用域可以分為:

全局[編輯 | 編輯原始碼]

使用 shell 初始化文件[編輯 | 編輯原始碼]

大多數 Linux 發行版告訴您在 /etc/profile 或其他位置更改或添加環境變量定義。請記住,還有一些特定於包的配置文件,其中包含變量設置,比如 /etc/locale.conf. 確保維護和管理環境變量,並注意可能包含環境變量的大量文件。原則上,任何 shell 腳本都可以用於初始化環境變量,但按照傳統的 UNIX 約定,這些語句只應出現在某些特定的文件中。

下列文件可用於定義系統上的全局環境變量,每個文件都有不同的限制:

  • /etc/environmentpam_env 模塊使用,與 shell 無關,所以無法使用腳本或通配符展開。此文件僅接受 variable=value 鍵值對格式。
  • /etc/profile 初始化登錄 shell 的變量。但它可以執行腳本(比如 /etc/profile.d/ 中的腳本) 並支持所有兼容 Bash 的 shell。
  • 特定於 shell 的配置文件——您的 Shell 的全局配置文件,初始化變量並運行腳本。例如 Bash#Configuration files (例如 ~/.bashrc) 或 Zsh#Startup/Shutdown files (例如 ~/.zshrc)。

以將 ~/bin~/scripts 加入對應用戶的 PATH 為例,可以將其放入首選的全局環境變量配置文件 /etc/profile/etc/bash.bashrc

set_path(){

    # Check if user id is 1000 or higher
    [ "$(id -u)" -ge 1000 ] || return

    for i in "$@";
    do
        # Check if the directory exists
        [ -d "$i" ] || continue

        # Check if it is not already in your $PATH.
        echo "$PATH" | grep -Eq "(^|:)$i(:|$)" && continue

        # Then append it to $PATH and export it
        export PATH="${PATH}:$i"
    done
}

set_path ~/bin ~/scripts

在不同 shell 間分享環境變量的一種方法是創建一個 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 模塊 pam_env(8) 從以下文件中按順序加載要在環境中設置的變量:/etc/security/pam_env.conf/etc/environment.

注意: 這些文件在其他文件之前讀取,特別是 ~/.profile, ~/.bash_profile and ~/.zshenv 之前。
警告: 讀取 ~/.pam_environment 已被棄用,不再起作用,參考 FS#68945

/etc/environment 必須由每行單獨的一個 VARIABLE=value 鍵值對組成,例如:

/etc/environment
EDITOR=nano

/etc/security/pam_env.conf 使用以下格式:

/etc/security/pam_env.conf
VARIABLE [DEFAULT=value] [OVERRIDE=value]

@{HOME} @{SHELL} 是特殊的變量,展開到 /etc/passwd 中的定義。以下示例說明了如何將 HOME 環境變量展開到另一個變量:

/etc/security/pam_env.conf
XDG_CONFIG_HOME   DEFAULT=@{HOME}/.config
注意: 變量 ${HOME} ${SHELL} 默認是未設置的,並不鏈接到 HOMESHELL 環境變量。

該格式還允許在其它變量值中使用 ${VARIABLE} 展開已定義的變量,如下所示:

/etc/security/pam_env.conf
GOPATH DEFAULT=${XDG_DATA_HOME}/go

VARIABLE=value 鍵值對也是允許的,但不支持變量展開。請參考 pam_env.conf(5).

按用戶[編輯 | 編輯原始碼]

有時並不希望定義全局環境變量,比如要把 /home/my_user/bin 加入 PATH 變量但是不影響其它用戶。本地環境變量可以在下面文件定義:

要修改本地用戶的 PATH 變量,將以下內容加入 ~/.bash_profile

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

要更新變量,重新登錄或 source 文件: $ source ~/.bash_profile

注意: dbus 守護進程和 systemd 用戶實例不會繼承任何 .bashrc 等文件定義的環境變量。這意味着 dbus 啟動的程序如 GNOME Files 默認不會使用這些變量,請參考 Systemd/用戶#環境變量
提示:您可以用 export -p 來查看為用戶會話設置的全局和局部環境變量。

圖形環境[編輯 | 編輯原始碼]

如果環境變量僅影響圖形應用程序,您可能希望僅通過在圖形會話中設置它來限制其範圍。

Xorg 會話[編輯 | 編輯原始碼]

修改 Xorg 會話環境的過程取決於其啟動方式:

雖然腳本的結尾取決於它是哪個文件,且任何高級語法都取決於所使用的 shell,但基本用法是通用的:

~/.xprofile, ~/.xinitrc, or ~/.xsession
...
export GUI_VAR=value
...
Wayland 會話[編輯 | 編輯原始碼]

由於 Wayland 不啟動任何 Xorg 相關文件,因此 GDMKDE Plasma 讀取 systemd 用戶環境變量

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

其他支持 Wayland 會話的顯示管理器(例如 SDDM)還沒有提供這種支持。然而,LightDMSDDM 也為 Wayland 會話的登錄 shell 讀取啟動腳本。

greetd 同時讀取 /etc/profile~/.profile——該行為由其 source_profile 控制,默認開啟。

本文或本章節的語言、語法或風格需要改進。參考:幫助:風格

原因:The following depends on run-parts.(在Talk:環境變量討論)

If your display manager sources startup scripts like ~/.bash_profile and you want to use environment.d, you can source it like so:

~/.bash_profile
# use systemd-environment-d-generator(8) to generate environment, and export those variables
set -o allexport
source <(/usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)
set +o allexport
注意: Other generators in /usr/lib/systemd/user-environment-generators like 60-flatpak may not quote the values of environment variables. In this case the output should be sourced with export -- "$(/usr/lib/systemd/user-environment-generators/60-flatpak)"


按桌面會話[編輯 | 編輯原始碼]

一些圖形環境(如 KDE Plasma)支持在登錄時執行 shell 腳本,它們可以用來設置環境變量。示例請參考 KDE#Autostart

按單個程序[編輯 | 編輯原始碼]

要僅為特定應用程序而不是整個會話設置環境變量,請編輯應用程序的 .desktop 文件。請參考 Desktop entries#修改環境變量

可以通過 Steam#Launch options 選項修改 Steam 遊戲的環境變量。

按會話或 shell[編輯 | 編輯原始碼]

本文或本章節的事實準確性存在爭議。

原因: Since PATH is exported by default (at least in Bash; see declare -p | grep PATH), both PATH=... and export PATH=... do the same; it is probably better to use another variable for at least one of these examples.(在 Talk:環境變量 中討論)


有時只需要臨時變量。您可能希望從創建的特定目錄臨時運行可執行文件,而無需鍵入每個文件的絕對路徑,或者在簡短的臨時 shell 腳本中使用該路徑。

例如,可以在當前 shell 中定義 PATH 變量,或者使用 export 命令為所有 shell 定義,直到註銷會話。添加一個特定會話目錄到 PATH

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

添加一個特定 shell 目錄到 PATH

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

示例[編輯 | 編輯原始碼]

以下部分列出了 Linux 系統使用的一些常見環境變量,並描述了它們的值。

  • XDG_CURRENT_DESKTOP 是一個 freedesktop.org 變量,包含冒號分隔的字符串列表,標識當前 desktop environment [5]. 活躍開發中環境的標準化值有 GNOME, GNOME-Flashback, KDE, LXDE, LXQt, MATE, TDE, Unity, XFCE, EDE, Cinnamon, PantheonDDE [6].
    • Cinnamon 的註冊時間比其他桌面環境. 因此,一些軟件依舊使用註冊前的值 X-CINNAMON, 比如 Qt[7].
    • Hyprland is informally recognized for Hyprland.
  • DE 是一個過時的變量,表明使用的桌面環境。沒有權威的文檔說明可能的值,但 xdg-utils 為許多桌面環境提供了參考。
  • DESKTOP_SESSION 類似於 DE,但是用於 LXDE 桌面環境:當 DESKTOP_SESSION 設置為 LXDE, xdg-open 會使用 pcmanfm 文件關聯。
  • WINDOW_MANAGER 變量有時用於選擇桌面環境要使用的 window manager,與其他變量不同,這裡的變量是由已經選擇的顯示管理器或桌面環境設置的,供其他程序讀取。
  • PATH 包含以冒號分隔的目錄列表,系統在其中查找可執行文件。當一個一般命令 (例如 ls, systemctlpacman) 由 shell 解釋時 (如 bashzsh), shell 從列表包含的目錄中尋找與命令同名的可執行程序並執行。要運行不在 PATH 中的應用程序,必須給出可執行程序的相對或絕對路徑,例如 ./a.out/bin/ls.
注意: 安全起見,建議不要將當前工作目錄 (.) 加入 PATH,因為它可能欺騙用戶執行惡意命令。
  • HOME 包含當前用戶主目錄的路徑。應用程序可以使用此變量將配置文件等與運行它的用戶相關聯。
  • PWD 包含工作目錄的路徑。
  • OLDPWD 包含前一個工作目錄的路徑,即執行最後一個 cd 之前的 PWD 的值。
  • TERM 包含正在運行的終端類型,例如 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 命令在其中搜索手冊頁。
注意:/etc/profile中,有一條注釋說 "Man 比我們更擅長解決這個問題", 因此該變量通常不設置。請參考 manpath(5).
  • INFODIR 包含以冒號分隔的目錄列表,info 命令在其中搜索信息頁,比如 /usr/share/info:/usr/local/share/info
  • TZ 可用於為用戶設置與系統區域不同的時區。/usr/share/zoneinfo/ 中列出的時區可作參考,例如 TZ=":/usr/share/zoneinfo/Pacific/Fiji". 當 TZ 變量指向 zoneinfo 文件時,應以冒號開頭 GNU 手冊.

默認程序[編輯 | 編輯原始碼]

  • SHELL 包含用戶首選 shell 的路徑。請注意,這不一定是當前運行的 shell。在沒有值的情況下,Bash 將自動將此變量設置為 /etc/passwd中定義的用戶登錄 shell,如果無法確定,則將此變量設為 /bin/sh.
  • PAGER 包含運行用於列出文件內容的程序的命令,例如 /bin/less.
  • EDITOR 包含運行用於編輯文件的輕量級程序的命令,例如 /usr/bin/nano. 本例中,你可以編寫 X 下的geditnano 的交互式切換:
 [ -n "$DISPLAY" ] && export EDITOR=gedit || export EDITOR=nano
  • VISUAL 包含運行完整編輯器的命令,該編輯器用於更高要求的任務,如編輯郵件 (例如 vi, vim, emacs 等)。
  • BROWSER 包含 web 瀏覽器的路徑。有助於在交互式 shell 配置文件中進行設置,以便根據圖形環境的可用性對其進行動態更改,例如 X:
 [ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
提示:這些默認程序也可以根據是否運行 Wayland compositor 而配置,需要檢測的是 WAYLAND_DISPLAY 環境變量。

參閱[編輯 | 編輯原始碼]