環境變量
環境變量是一個具名對象,包含可被一個或多個應用程式使用的數據。簡單來說,它是具有一對名稱和值的變量。環境變量的值可以是文件系統上所有可執行程序的位置,默認的編輯器,系統本地化設置等。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. - LightDM[2] 和 SDDM[3] 為登錄 shell 讀取額外啟動腳本,比如
~/.bash_profile
為 bash 或~/.zprofile
和~/.zlogin
為 zsh [4]
雖然腳本的結尾取決於它是哪個文件,且任何高級語法都取決於所使用的 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)還沒有提供這種支持。然而,LightDM 和 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 set -o allexport source <(/usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator) set +o allexport
/usr/lib/systemd/user-environment-generators
like 60-flatpak
may not quote the values of environment variables. In this case the output should be sourced with export -- "$(/usr/lib/systemd/user-environment-generators/60-flatpak)"
按桌面會話[編輯 | 編輯原始碼]
一些圖形環境(如 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 [5]. 活躍開發中環境的標準化值有GNOME
,GNOME-Flashback
,KDE
,LXDE
,LXQt
,MATE
,TDE
,Unity
,XFCE
,EDE
,Cinnamon
,Pantheon
和DDE
[6].
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
環境變量。