环境变量

出自 ArchWiki
(重定向自 Define)

环境变量是一个已命名的对象,其中包含一个或多个应用程序使用的数据。简单来说,它是一个具有名称和值的变量。环境变量的值例如可以是文件系统中所有可执行文件的位置、应使用的默认编辑器或系统区域设置。Linux 新用户可能经常发现这种管理设置的方式有点难以管理。但是,环境变量提供了一种在 Linux 中多个应用程序和进程之间共享配置设置的简单方法。

工具

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

$ printenv
注意: 有些环境变量是用户特定的。通过比较非特权用户和 root 身份下 printenv 的输出来检查。

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

$ env EDITOR=vim xterm

shell 内建命令 set(1p) 允许您更改 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)。

在本示例中,我们将创建一个函数,以将多个目录(例如 ~/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 之间共享环境变量的一种方法是创建一个没有任何注释、空行或空格 (bash) 的文件,该文件可以直接由 envsubst 读取(灵感来自 [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~/.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 等位置设置的任何环境变量。这意味着,例如,像 GNOME Files 这样的 dbus 激活的程序默认情况下不会使用它们。请参阅 systemd/User#环境变量
提示: 您可以执行 export -p 来查看为用户会话声明的全局和本地环境变量。

图形环境

如果环境变量仅影响图形应用程序,您可能希望通过仅在图形会话中设置它来限制其作用域。按作用域递减顺序排列

每个桌面环境会话

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

每个 Xorg 会话

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

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

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

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

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

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

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

如果您的显示管理器 source 启动脚本(如 ~/.bash_profile)并且您想使用 environment.d,则可以像这样 source 它

~/.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 文件。有关说明,请参见 桌面条目#修改环境变量

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

每个会话或 shell

此条目或章节的实际准确性存在争议。

原因: 由于 PATH 默认导出(至少在 Bash 中;请参见 declare -p | grep PATH),PATH=...export PATH=... 都执行相同的操作;最好对这些示例中的至少一个使用另一个变量。(在 Talk:Environment variables 中讨论)

有时只需要临时变量。可能需要从创建的特定目录临时运行可执行文件,而无需键入每个可执行文件的绝对路径,或者在临时的简短 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 变量,其中包含当前桌面环境标识为 [4] 的冒号分隔的字符串列表。积极开发的标准化环境值为 GNOMEGNOME-FlashbackKDELXDELXQtMATETDEUnityXFCEEDECinnamonPantheonDDE [5]
    • Cinnamon 的注册时间 晚于 其余桌面环境。因此,某些软件可能仍会预期其预注册值 X-CINNAMON,例如 Qt[6]
    • Hyprland 在非正式场合被 Hyprland 认可。
  • DE 是一个遗留变量,指示正在使用的桌面环境。对于可能的取值没有中心文档,但 xdg-utils 为许多桌面环境提供了参考。
  • DESKTOP_SESSION 是另一个遗留变量,类似于 DE 但不太常见。它可能是会话的 桌面条目 的路径,位于 /usr/share/xsessions/[7]
  • WINDOW_MANAGER 是一个变量,有时用于选择要在桌面环境中使用的 窗口管理器,而不是此处由已选择的显示管理器或桌面环境设置的其他变量,以供其他程序读取。
  • PATH 包含一个冒号分隔的目录列表,您的系统在其中查找可执行文件。当 shell(例如 bashzsh)解释常规命令(例如 lssystemctlpacman)时,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"。根据 GNU 手册,当将 TZ 变量指向 zoneinfo 文件时,它应以冒号开头。

默认程序

  • 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 合成器 正在运行,也可以有条件地设置这些默认程序,方法是使用 WAYLAND_DISPLAY 环境变量。

参见