環境變量 - Arch Linux 中文维基

跳至內容

# 環境變量

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 Environment variables，最近一次同步於 2024-11-24，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- Default applications
- systemd/用戶#環境變量

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

## 工具

coreutils包 軟體包含程序 printenv 和 env . 要顯示當前環境變量的值：

    $ 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 服務要求在明確的位置設置環境變量。變量的作用域可以分為:

- 全局: 任何用戶運用的所有程序，不包含 systemd 服務.
- 按用戶: 某個用戶運行的程序，不包含用戶 systemd 服務 (需參考 Systemd/User#Environment variables) 或圖形程序(需參考 #圖形環境).

### 全局

#### 使用 shell 初始化文件

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

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

- `/etc/environment` 被 pam_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 間共享環境變量

在不同 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)

注意：這種做法的缺點是：變量值不可含空格。比如，不能使用這種做法定義`EDITOR="emacsclient -t"`。

#### 使用 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}` 默認是未設置的，並不連結到 `HOME` 和 `SHELL` 環境變量。

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

    /etc/security/pam_env.conf

    GOPATH DEFAULT=${XDG_DATA_HOME}/go

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

### 按用戶

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

- shell 的用戶配置文件，例如 Bash#Configuration files 或 Zsh#Startup/Shutdown files。
  - 除非您將變量的範圍限制為您打開的終端（例如命令行程序），您需要修改登錄 shell。
- systemd 用戶環境變量讀取自 `~/.config/environment.d/*.conf`。

要修改本地用戶的 `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 會話環境的過程取決於其啟動方式：

- 大多數顯示管理器讀取 xprofile.
- startx 和 SLiM 執行 xinitrc.
- XDM 執行 `~/.xsession`；請參考 XDM#Defining the session.
- LightDM[2] 和 SDDM[3] 為登錄 shell 讀取額外啟動腳本，比如 `~/.bash_profile` 為 bash 或 `~/.zprofile` 和 `~/.zlogin` 為 zsh [4]

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

    ~/.xprofile, ~/.xinitrc, or ~/.xsession

    ...
    export GUI_VAR=value
    ...

##### Wayland 會話

由於 Wayland 不啟動任何 Xorg 相關文件，因此 GDM 和 KDE Plasma 讀取 systemd 用戶環境變量。

    ~/.config/environment.d/envvars.conf

    GUI_VAR=value

其他支持 Wayland 會話的顯示管理器（例如 SDDM）還沒有提供這種支持。然而，LightDM 和 SDDM 也為 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`, `Pantheon` 和 `DDE` [6].
  - Cinnamon 的註冊時間比其他桌面環境晚. 因此，一些軟體依舊使用註冊前的值 `X-CINNAMON`, 比如 Qt[7].
  - `Hyprland` is informally recognized for Hyprland.

- `XDG_SESSION_DESKTOP` 類似於 `XDG_CURRENT_DESKTOP`, 但只允許單個字符串。儘管名字包含 XDG，但它並沒有由 freedesktop.org 標準化。

- `DE` 是一個過時的變量，表明使用的桌面環境。沒有權威的文檔說明可能的值，但 xdg-utils 為許多桌面環境提供了參考。

- `DESKTOP_SESSION` 類似於 `DE`，但是用於 LXDE 桌面環境：當 `DESKTOP_SESSION` 設置為 `LXDE`, xdg-open 會使用 pcmanfm 文件關聯。

- `WINDOW_MANAGER` 變量有時用於選擇桌面環境要使用的 window manager，與其他變量不同，這裡的變量是由已經選擇的顯示管理器或桌面環境設置的，供其他程序讀取。

- `PATH` 包含以冒號分隔的目錄列表，系統在其中查找可執行文件。當一個一般命令 (例如 ls, systemctl 或 pacman) 由 shell 解釋時 (如 bash 或 zsh)， shell 從列表包含的目錄中尋找與命令同名的可執行程序並執行。要運行不在 `PATH` 中的應用程式，必須給出可執行程序的相對或絕對路徑，例如 `./a.out` 或 `/bin/ls`.

注意：安全起見，建議不要將當前工作目錄 (`.`) 加入 `PATH`，因為它可能欺騙用戶執行惡意命令。

- `HOME` 包含當前用戶主目錄的路徑。應用程式可以使用此變量將配置文件等與運行它的用戶相關聯。

- `PWD` 包含工作目錄的路徑。

- `OLDPWD` 包含前一個工作目錄的路徑，即執行最後一個 cd 之前的 `PWD` 的值。

- `TERM` 包含正在運行的終端類型，例如 `xterm-256color`. 它由運行在終端中，希望使用終端特定功能的程序使用。

- `MAIL` 包含傳入電子郵件的位置。傳統的設置是 `/var/spool/mail/$LOGNAME`.

- `ftp_proxy` 和 `http_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 下的gedit 或 nano 的交互式切換：

     [ -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` 環境變量。

## 參閱

- Gentoo:Handbook:X86/Working/EnvVar
- Ubuntu Community Wiki - Environment Variables

分類：​

- 系統管理
- 使用「模板:風格」標記的頁面或章節

隱藏分類：​

- 使用「模板:準確性」標記的頁面或章節

環境變量
新增話題