环境变量
环境变量是一个具名对象,包含可被一个或多个应用程序使用的数据。简单来说,它是具有一对名称和值的变量。环境变量的值可以是文件系统上所有可执行程序的位置,默认的编辑器,系统本地化设置等。Linux 新用户可能觉得这种管理变量的方式有点混乱。但是环境变量提供了一种在多个程序和进程间共享配置的简单方式。
工具[编辑 | 编辑源代码]
coreutils包 软件包含程序 printenv 和 env . 要显示当前环境变量的值:
$ 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 间分享环境变量的一种方法是创建一个 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)
使用 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
export -p
来查看为用户会话设置的全局和局部环境变量。图形环境[编辑 | 编辑源代码]
如果环境变量仅影响图形应用程序,您可能希望仅通过在图形会话中设置它来限制其范围。
Xorg 会话[编辑 | 编辑源代码]
修改 Xorg 会话环境的过程取决于其启动方式:
- 大多数显示管理器读取 xprofile.
- startx 和 SLiM 执行 xinitrc.
- XDM 执行
~/.xsession
;请参考 XDM#Defining the session. - SDDM 为登录 shell 读取额外启动脚本,比如
~/.bash_profile
为 bash 或~/.zprofile
和~/.zlogin
为 zsh [2]
虽然脚本的结尾取决于它是哪个文件,且任何高级语法都取决于所使用的 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)还没有提供这种支持。然而,SDDM 也为 Wayland 会话的登录 shell 读取启动脚本。
greetd 同时读取 /etc/profile
和 ~/.profile
——该行为由其 source_profile
控制,默认开启。
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 export $(run-parts /usr/lib/systemd/user-environment-generators | sed '/:$/d; /^$/d' | xargs)
/usr/lib/systemd/user-environment-generators
, which may or may not be desirable. Feel free to run /usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator
directly instead.按桌面会话[编辑 | 编辑源代码]
一些图形环境(如 KDE Plasma)支持在登录时执行 shell 脚本,它们可以用来设置环境变量。示例请参考 KDE#Autostart
按单个程序[编辑 | 编辑源代码]
要仅为特定应用程序而不是整个会话设置环境变量,请编辑应用程序的 .desktop 文件。请参考 Desktop entries#修改环境变量。
可以通过 Steam#Launch options 选项修改 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 变量,包含冒号分隔的字符串列表,标识当前 desktop environment [3]. 活跃开发中环境的标准化值有GNOME
,GNOME-Flashback
,KDE
,LXDE
,LXQt
,MATE
,TDE
,Unity
,XFCE
,EDE
,Cinnamon
,Pantheon
和DDE
[4].- Cinnamon 的注册时间比其他桌面环境晚. 因此,一些软件依旧使用注册前的值
X-CINNAMON
, 比如 Qt 最新的6.3版本 [5].
- Cinnamon 的注册时间比其他桌面环境晚. 因此,一些软件依旧使用注册前的值
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
BROWSER
包含 web 浏览器的路径。有助于在交互式 shell 配置文件中进行设置,以便根据图形环境的可用性对其进行动态更改,例如 X:
[ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
WAYLAND_DISPLAY
环境变量。