环境变量
环境变量是一个命名对象,其中包含一个或多个应用程序使用的数据。简单来说,它是一个具有名称和值的变量。环境变量的值可以是例如文件系统中所有可执行文件的位置、应使用的默认编辑器或系统区域设置。Linux 新手通常会发现这种管理设置的方式有点难以管理。但是,环境变量提供了一种在 Linux 中多个应用程序和进程之间共享配置设置的简单方法。
实用程序
coreutils 软件包包含程序 printenv 和 env。要列出当前环境变量及其值
$ 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 服务要求您在特定位置设置变量才能使其生效。环境变量的作用域分为它们影响的上下文
- 全局:任何用户运行的所有程序,不包括 systemd 服务。
- 按用户:特定用户运行的所有程序,不包括用户 systemd 服务(参见 Systemd/User#环境变量)或图形应用程序(参见 #图形环境)。
全局地
使用 shell 初始化文件
大多数 Linux 发行版都告诉您在 /etc/profile
或其他位置更改或添加环境变量定义。请记住,还有包含变量设置的软件包特定配置文件,例如 /etc/locale.conf
。请务必维护和管理环境变量,并注意可能包含环境变量的众多文件。原则上,任何 shell 脚本都可以用于初始化环境变量,但按照传统的 UNIX 约定,这些语句应仅出现在某些特定文件中。
以下文件可用于在您的系统上定义全局环境变量,每个文件都有不同的限制
/etc/environment
由 pam_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}
未链接到 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
变量,但不希望系统上的所有其他用户都在其 PATH
中拥有该变量。可以在许多不同的文件中定义本地环境变量
- 您的 shell 的用户配置文件,例如 Bash#配置文件 或 Zsh#启动/关闭文件。
- 除非您将变量的作用域限制为打开的终端(例如,仅限命令行应用程序),否则您正在寻找修改登录 shell。
- systemd 用户环境变量从
~/.config/environment.d/*.conf
读取。
要将目录添加到本地使用的 PATH
,请将以下内容放入 ~/.bash_profile
中
export PATH="${PATH}:/home/my_user/bin"
要更新变量,请重新登录或 source 该文件:$ source ~/.bash_profile
。
~/.bashrc
等位置设置的任何环境变量。这意味着,例如,dbus 激活的程序(如 GNOME 文件)默认情况下不会使用它们。请参阅 systemd/User#环境变量。export -p
以查看为用户会话声明的全局和本地环境变量。图形环境
如果环境变量仅影响图形应用程序,您可能希望通过仅在图形会话中设置它来限制其作用域。按作用域递减顺序排列
- #每个 Xorg 会话 和 #每个 Wayland 会话 影响整个图形会话,当然包括 DE。
- #每个桌面环境会话 影响在图形会话中生成的应用程序,可能包括 DE 本身。
- #每个应用程序 仅影响特定的图形应用程序。
每个桌面环境会话
某些图形环境(例如 KDE Plasma)支持在登录时执行 shell 脚本:它们可用于设置环境变量。有关示例,请参阅 KDE#自动启动。
每个 Xorg 会话
修改 Xorg 会话环境的过程取决于它的启动方式
- 大多数 显示管理器 source xprofile。
- startx 和 SLiM 执行 xinitrc。
- XDM 执行
~/.xsession
;请参阅 XDM#定义会话。 - LightDM[2] 和 SDDM[3] 还会为登录 shell 附加 startup 脚本,例如 bash 的
~/.bash_profile
或 zsh 的~/.zprofile
和~/.zlogin
。
虽然脚本的结尾取决于它是哪个文件,并且任何高级语法都取决于使用的 shell,但基本用法是通用的
~/.xprofile, ~/.xinitrc, or ~/.xsession
... export GUI_VAR=value ...
每个 Wayland 会话
由于 Wayland 不启动任何与 Xorg 相关的文件,因此 GDM 和 KDE Plasma 转而 source systemd 用户环境变量。
~/.config/environment.d/envvars.conf
GUI_VAR=value
尚无其他支持 Wayland 会话的显示管理器(例如 SDDM)为此提供直接支持。但是,LightDM 和 SDDM 也会在 Wayland 会话上为登录 shell 附加启动脚本。
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
有时只需要临时变量。人们可能希望临时运行从创建的特定目录中的可执行文件,而无需键入每个可执行文件的绝对路径,或者在简短的临时 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]。积极开发的环境的标准值包括GNOME
、GNOME-Flashback
、KDE
、LXDE
、LXQt
、MATE
、TDE
、Unity
、XFCE
、EDE
、Cinnamon
、Pantheon
和DDE
[5]。
XDG_SESSION_DESKTOP
与XDG_CURRENT_DESKTOP
类似,但仅允许单个字符串。尽管名称如此,但 它不是由 freedesktop.org 标准化的。
DE
是一个遗留变量,指示正在使用的桌面环境。没有关于可能值的中心文档,但 xdg-utils 为许多桌面环境提供了参考。
WINDOW_MANAGER
是一个有时用于选择要在桌面环境中使用的窗口管理器的变量,与此处由已选择的显示管理器或桌面环境设置的其他变量相反,供其他程序读取。
PATH
包含一个以冒号分隔的目录列表,您的系统在其中查找可执行文件。当 shell(例如 bash 或 zsh)解释常规命令(例如 ls、systemctl 或 pacman)时,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 在其中搜索 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
变量指向 zoneinfo 文件时,它应以冒号开头,请参阅 GNU 手册。
默认程序
SHELL
包含用户首选 shell 的路径。请注意,这不一定是当前正在运行的 shell。如果它没有值,Bash 将自动将此变量设置为用户登录 shell(如/etc/passwd
中定义)或/bin/sh
(如果无法确定)。
PAGER
包含运行用于列出文件内容的程序的命令,例如/bin/less
。
EDITOR
包含运行用于编辑文件的轻量级程序的命令,例如/usr/bin/nano
。例如,您可以编写 gedit 在 X 下或 nano 之间的交互式切换,在此示例中
[ -n "$DISPLAY" ] && export EDITOR=gedit || export EDITOR=nano
BROWSER
包含 Web 浏览器的路径。有助于在交互式 shell 配置文件中设置,以便可以根据图形环境的可用性动态更改它,例如 X
[ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
WAYLAND_DISPLAY
环境变量。