环境变量 - 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

分类：​

- 系统管理
- 使用“模板:风格”标记的页面或章节

隐藏分类：​

- 使用“模板:准确性”标记的页面或章节

环境变量
添加话题