环境变量
环境变量是命名的对象,其中包含一个或多个应用程序使用的数据。简单来说,它是一个具有名称和值的变量。环境变量的值可以是例如文件系统中所有可执行文件的位置、应使用的默认编辑器或系统区域设置。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
等位置设置的任何环境变量。这意味着,例如,像 GNOME Files 这样的 dbus 激活程序默认情况下不会使用它们。参见 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 提供启动脚本,例如 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]。积极开发的Standardized环境的值为GNOME
、GNOME-Flashback
、KDE
、LXDE
、LXQt
、MATE
、TDE
、Unity
、XFCE
、EDE
、Cinnamon
、Pantheon
和DDE
[5]。
XDG_SESSION_DESKTOP
与XDG_CURRENT_DESKTOP
类似,但仅允许单个字符串。尽管名称如此,它不是由 freedesktop.org 标准化的。
DE
是一个遗留变量,指示正在使用的desktop environment。没有关于可能值的中心文档,但 xdg-utils 为许多桌面环境提供了参考。
WINDOW_MANAGER
是一个有时用于选择要在桌面环境中使用的窗口管理器的变量,与此处由已选择的显示管理器或桌面环境设置的其他变量相反,供其他程序读取。
PATH
包含一个冒号分隔的目录列表,您的系统在其中查找可执行文件。当 shell(例如 bash 或 zsh)解释常规命令(例如 ls、systemctl 或 pacman)时,shell 会在列出的目录中查找与您的命令同名的可执行文件,并执行它。要运行未在PATH
中列出的可执行文件,必须给出可执行文件的相对路径或绝对路径,例如./a.out
或/bin/ls
。
.
) 包含到您的 PATH
中,出于安全原因,因为它可能会诱使用户执行恶意命令。HOME
包含当前用户主目录的路径。应用程序可以使用此变量将配置文件等与运行它的用户关联起来。
PWD
包含工作目录的路径。
OLDPWD
包含上一个工作目录的路径,即上次执行 cd 之前PWD
的值。
TERM
包含正在运行的terminal 的类型,例如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 将自动将此变量设置为用户在/etc/passwd
中定义的登录 shell,如果无法确定,则设置为/bin/sh
。
PAGER
包含运行用于列出文件内容的程序的命令,例如/bin/less
。
EDITOR
包含运行用于编辑文件的轻量级程序的命令,例如/usr/bin/nano
。例如,您可以编写一个在 X 下的 gedit 或 nano 之间进行交互式切换的程序,在此示例中
[ -n "$DISPLAY" ] && export EDITOR=gedit || export EDITOR=nano
BROWSER
包含 Web 浏览器的路径。有助于在交互式 shell 配置文件中设置,以便可以根据图形环境的可用性动态更改它,例如 X
[ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
WAYLAND_DISPLAY
环境变量。