跳转至内容

环境变量

来自 ArchWiki
(重定向自 XDG CURRENT DESKTOP)

环境变量是一个包含一个或多个应用程序使用的数据的命名对象。简单来说,它是一个有名称和值的变量。环境变量的值可以是文件系统中所有可执行文件的位置、应该使用的默认编辑器,或者系统区域设置。初次接触 Linux 的用户可能会觉得这种管理设置的方式有点难以驾驭。然而,环境变量提供了一种在 Linux 中共享多个应用程序和进程之间配置设置的简单方法。

工具

coreutils 包包含 printenvenv 程序。要列出当前环境变量及其值

$ printenv
注意 某些环境变量是用户特定的。通过比较未授权用户和 root 用户的 printenv 输出,可以进行检查。

env 工具可以用于在修改后的环境中运行命令。以下示例将启动 xterm,并将环境变量 EDITOR 设置为 vim。这不会影响全局环境变量 EDITOR

$ env EDITOR=vim xterm

set(1p) shell 内建命令允许你更改 shell 选项的值,设置位置参数,并显示 shell 变量的名称和值。

每个进程将其环境存储在 /proc/$PID/environ 文件中。该文件包含由空字符 (\x0) 分隔的每个键值对。可以使用 sed 来获得更易读的格式,例如 sed 's:\x0:\n:g' /proc/$PID/environ

定义变量

为了避免不必要地污染环境,你应该尽量限制变量的范围。实际上,图形会话和 systemd 服务要求你在特定位置设置变量才能生效。环境变量的范围被分解为它们影响的上下文

全局

使用 shell 初始化文件

大多数 Linux 发行版会告诉你更改或添加环境变量定义在 /etc/profile 或其他位置。请记住,还有包含变量设置的特定于包的配置文件,例如 /etc/locale.conf。请确保维护和管理环境变量,并注意可能包含环境变量的众多文件。原则上,任何 shell 脚本都可以用于初始化环境变量,但遵循传统的 UNIX 约定,这些语句应该只存在于某些特定文件中。

以下文件可用于定义系统上的全局环境变量,每个文件都有不同的限制

  • /etc/environmentpam_env 模块使用,并且与 shell 无关,因此不能使用脚本或 glob 扩展。该文件只接受 variable=value 对。
  • /etc/profile 仅为登录 shell 初始化变量。但是,它会运行脚本(例如 /etc/profile.d/ 中的脚本),并且可以被所有 Bourne shell 兼容的 shell 使用。
  • 特定于 shell 的配置文件 - 你 shell 的全局配置文件,初始化变量并运行脚本。例如 Bash#配置文件(例如 ~/.bashrc)或 Zsh#启动/关闭文件(例如 ~/.zshrc)。

以下 Bash 辅助函数可用于将多个目录追加到 PATH 环境变量。将函数添加到定义环境变量的文件顶部(例如 ~/.bashrc)。该函数只会添加实际存在于文件系统中的目录,并且会避免创建重复条目。

add_paths() {
  for d in "$@"; do
    [[ -d "$d" && ! "$PATH" =~ (^|:)$d(:|$) ]] && PATH="$PATH:$d"
  done
}

add_paths ~/bin ~/scripts

大多数 shell(包括 Bash、Zsh 和 fish)允许使用 export 命令将变量添加到环境中。这允许在通用文件(如 ~/my-environment.sh)中定义环境变量。

~/my-environment.sh
export EDITOR=vim
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"

然后可以从 shell 启动文件中 source 此文件。

~/.bashrc
source ~/my-environment.sh
~/.config/fish/config.fish
source ~/my-environment.sh

使用 pam_env

PAM 模块 pam_env(8) 按顺序从以下文件中加载要设置在环境中的变量:/etc/security/pam_env.conf/etc/environment

  • 这些文件在读取其他文件之前被读取,尤其是在读取 ~/.profile~/.bash_profile~/.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 中包含它。可以在许多不同的文件中定义本地环境变量。

要为本地使用将目录添加到 PATH,请将以下内容放入 ~/.bash_profile

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

要更新变量,请重新登录或 source 文件:$ source ~/.bash_profile

注意 dbus 守护进程和 systemd 的用户实例不会继承在 ~/.bashrc 等位置设置的任何环境变量。这意味着,例如,dbus 激活的程序(如 GNOME Files)默认不会使用它们。参见 systemd/User#环境变量
提示 你可以发出 export -p 来查看为用户会话声明的全局和本地环境变量。

图形环境

如果环境变量仅影响图形应用程序,你可能希望通过仅在图形会话中设置它来限制其范围。按范围递减的顺序:

每个桌面环境会话

某些图形环境(例如 KDE Plasma)支持在登录时执行 shell 脚本:这些脚本可用于设置环境变量。例如,参见 KDE#自启动

每个 Xorg 会话

修改 Xorg 会话环境的过程取决于它的启动方式。

尽管脚本的结尾取决于它是哪个文件,并且任何高级语法都取决于使用的 shell,但基本用法是通用的。

~/.xprofile, ~/.xinitrc, or ~/.xsession
...
export GUI_VAR=value
...
每个 Wayland 会话

由于 Wayland 不会启动任何与 Xorg 相关的 Xorg 文件,GDMKDE Plasma 则 source systemd 用户环境变量

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

其他支持 Wayland 会话的显示管理器(例如 SDDM)目前不提供对此的直接支持。但是,LightDMSDDM 也会为 Wayland 会话 source 登录 shell 的启动脚本。

greetd 也 source /etc/profile~/.profile - 此行为由其 source_profile 设置控制,默认启用。

如果你的显示管理器 source 了 ~/.bash_profile 这类启动脚本,并且你想使用 environment.d,你可以这样做:

~/.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
注意 /usr/lib/systemd/user-environment-generators 中的其他生成器,如 60-flatpak,可能不会引用环境变量的值。在这种情况下,输出应使用 export -- "$(/usr/lib/systemd/user-environment-generators/60-flatpak)" 来 source。
每个应用程序

要仅为特定应用程序而不是整个会话设置环境变量,请编辑应用程序的 .desktop 文件。有关说明,请参见 Desktop entries#修改环境变量

对于 Steam 游戏,你可以通过编辑其启动选项来配置程序的运行环境;参见 Steam#启动选项

每个会话或 shell

有时只需要临时变量。一个人可能希望临时从特定目录运行可执行文件,而不必每次都输入完整的 PATH,或者在简短的临时 shell 脚本中使用 PATH

例如,要将特定于会话的目录添加到 PATH,请使用:

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

要仅将特定于 shell 的目录添加到 PATH,请使用:

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

在 Bash 中,PATH 默认已导出,因此上述两者在被覆盖之前都会对子进程可见。为了更好地说明导出变量和非导出变量之间的区别,请考虑以下内容:

$ MYVAR="shell-only"
$ bash -c 'echo $MYVAR'  # prints nothing

$ export MYVAR="session-wide"
$ bash -c 'echo $MYVAR'  # prints: session-wide

示例

下一节列出了 Linux 系统使用的许多常见环境变量,并描述了它们的值。

  • XDG_CURRENT_DESKTOP 是一个 freedesktop.org 变量,包含一个冒号分隔的字符串列表,表示当前 桌面环境 标识为 [3]。积极开发的桌面环境的标准化值包括 GNOMEGNOME-FlashbackKDELXDELXQtMATETDEUnityXFCEEDECinnamonPantheonDDE [4]
    • Cinnamon 比其他桌面环境更晚注册。因此,一些软件可能仍然期望其注册前的值 X-CINNAMON,例如 Qt[5]
    • Hyprland 是为 Hyprland 非正式承认的。
  • DE 是一个旧变量,指示正在使用的桌面环境。没有关于可能值的中央文档,但 xdg-utils 提供了许多桌面环境的参考。
  • DESKTOP_SESSION 是另一个旧变量,与 DE 类似但不太常见。它可能是会话的 桌面条目 的路径,位于 /usr/share/xsessions/ [6]
  • WINDOW_MANAGER 是一个有时用于选择桌面环境中使用的窗口管理器的变量,而不是此处由已选择的显示管理器或桌面环境设置、供其他程序读取的其他变量。
  • PATH 包含一个冒号分隔的目录列表,系统会在其中查找可执行文件。当一个常规命令(例如 lssystemctlpacman)被 shell(例如 bashzsh)解释时,shell 会在列出的目录中查找与你的命令同名的可执行文件,并执行它。要运行未列在 PATH 中的可执行文件,必须提供可执行文件的相对或绝对路径,例如 ./a.out/bin/ls
注意 出于安全原因,建议不要将当前工作目录(.)包含在 PATH 中,因为它可能会欺骗用户执行恶意命令。
  • HOME 包含当前用户主目录的路径。应用程序可以使用此变量将其配置文件等与运行它的用户关联起来。
  • 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 在其中搜索 man 页。
注意/etc/profile 中,有一条注释说“Man 比我们更擅长解决这个问题”,所以这个变量通常应该保持未设置。参见 manpath(5)
  • INFODIR 包含一个冒号分隔的目录列表,info 命令在其中搜索 info 页,例如 /usr/share/info:/usr/local/share/info
  • TZ 可用于设置一个与系统区域不同的用户区域。/usr/share/zoneinfo/ 中列出的区域可用作参考,例如 TZ=":/usr/share/zoneinfo/Pacific/Fiji"。当将 TZ 变量指向区域信息文件时,根据 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 包含用于更复杂任务(例如编辑邮件)的完整编辑器的命令(例如 vivimemacs 等)。
  • BROWSER 包含 Web 浏览器的路径。在交互式 shell 配置文件中设置它很有用,以便它可以根据图形环境(如 X)的可用性进行动态更改。
[ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
提示 也可以使用 WAYLAND_DISPLAY 环境变量有条件地设置这些默认程序,前提是正在运行 Wayland 合成器

参见