环境变量

来自 Arch Linux 中文维基
(重定向自Environment variables

环境变量是一个具名对象,包含可被一个或多个应用程序使用的数据。简单来说,它是具有一对名称和值的变量。环境变量的值可以是文件系统上所有可执行程序的位置,默认的编辑器,系统本地化设置等。Linux 新用户可能觉得这种管理变量的方式有点混乱。但是环境变量提供了一种在多个程序和进程间共享配置的简单方式。

工具[编辑 | 编辑源代码]

coreutils 软件包含程序 printenvenv . 要显示当前环境变量的值:

$ printenv
注意: 一些环境变量是属于特定用户的. 比较一般用户和 root 用户的 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 服务要求在明确的位置设置环境变量。变量的作用域可以分为:

全局[编辑 | 编辑源代码]

使用 shell 初始化文件[编辑 | 编辑源代码]

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

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

  • /etc/environmentpam_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} 默认是未设置的,并不链接到 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 变量,将以下内容加入 ~/.bash_profile

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

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

注意: dbus 守护进程和 systemd 用户实例不会继承任何 .bashrc 等文件定义的环境变量。这意味着 dbus 启动的程序如 GNOME Files 默认不会使用这些变量,请参考 Systemd/用户#环境变量
提示:您可以用 export -p 来查看为用户会话设置的全局和局部环境变量。

图形环境[编辑 | 编辑源代码]

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

Xorg 会话[编辑 | 编辑源代码]

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

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

~/.xprofile, ~/.xinitrc, or ~/.xsession
...
export GUI_VAR=value
...
Wayland 会话[编辑 | 编辑源代码]

由于 Wayland 不启动任何 Xorg 相关文件,因此 GDMKDE Plasma 读取 systemd 用户环境变量

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

其他支持 Wayland 会话的显示管理器(例如 SDDM)还没有提供这种支持。然而,SDDM 也为 Wayland 会话的登录 shell 读取启动脚本。

greetd 同时读取 /etc/profile~/.profile——该行为由其 source_profile 控制,默认开启。

本文或本章节的语言、语法或风格需要改进。参考:帮助:风格

原因:The following depends on run-parts.(在Talk:环境变量讨论)

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)
注意: The above runs all executables in /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[编辑 | 编辑源代码]

本文或本章节的事实准确性存在争议。

原因: Since PATH is exported by default (at least in Bash; see declare -p | grep PATH), both PATH=... and export PATH=... do the same; it is probably better to use another variable for at least one of these examples.(在 Talk:环境变量 中讨论)


有时只需要临时变量。您可能希望从创建的特定目录临时运行可执行文件,而无需键入每个文件的绝对路径,或者在简短的临时 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 系统使用的一些常见环境变量,并描述了它们的值。

  • DE 是一个过时的变量,表明使用的桌面环境。没有权威的文档说明可能的值,但 xdg-utils 为许多桌面环境提供了参考。
  • DESKTOP_SESSION 类似于 DE,但是用于 LXDE 桌面环境:当 DESKTOP_SESSION 设置为 LXDE, xdg-open 会使用 pcmanfm 文件关联。
  • WINDOW_MANAGER 变量有时用于选择桌面环境要使用的 window manager,与其他变量不同,这里的变量是由已经选择的显示管理器或桌面环境设置的,供其他程序读取。
  • PATH 包含以冒号分隔的目录列表,系统在其中查找可执行文件。当一个一般命令 (例如 ls, systemctlpacman) 由 shell 解释时 (如 bashzsh), shell 从列表包含的目录中寻找与命令同名的可执行程序并执行。要运行不在 PATH 中的应用程序,必须给出可执行程序的相对或绝对路径,例如 ./a.out/bin/ls.
注意: 安全起见,建议不要将当前工作目录 (.) 加入 PATH,因为它可能欺骗用户执行恶意命令。
  • HOME 包含当前用户主目录的路径。应用程序可以使用此变量将配置文件等与运行它的用户相关联。
  • PWD 包含工作目录的路径。
  • 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 命令在其中搜索手册页。
注意:/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 下的geditnano 的交互式切换:
 [ -n "$DISPLAY" ] && export EDITOR=gedit || export EDITOR=nano
  • VISUAL 包含运行完整编辑器的命令,该编辑器用于更高要求的任务,如编辑邮件 (例如 vi, vim, emacs 等)。
  • BROWSER 包含 web 浏览器的路径。有助于在交互式 shell 配置文件中进行设置,以便根据图形环境的可用性对其进行动态更改,例如 X:
 [ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
提示:这些默认程序也可以根据是否运行 Wayland compositor 而配置,需要检测的是 WAYLAND_DISPLAY 环境变量。

参阅[编辑 | 编辑源代码]