設置環境變數的最佳發行版/外殼無關方式是什麼?
這個問題說明了一切。我目前使用 Arch Linux 和 zsh,但我想要一個(至少)在 VT 和 xterms 上都可以工作的解決方案,並且(希望,最好)如果我切換發行版或 shell 將繼續工作。
我在不同發行版的文件中聽到了對這個問題的截然不同的答案。Ubuntu 說“使用 .pam_environment”。我認為在 Arch 中他們推薦的內容取決於你的 shell。目前,我將所有內容都放在.profile中,如果 shell 由於某種原因(例如,如果 .bash_profile 存在,則為 bash),我會通過手動獲取它來覆蓋它。但似乎必須有更好的方法。
不幸的是,沒有完全可移植的位置來設置環境變數。最接近的兩個文件是
~/.profile
,這是傳統位置,可以在許多設置中開箱即用,以及**~/.pam_environment
**,一個現代、普通但有限的替代方案。放什麼
~/.pam_environment
所有使用PAM並啟用此文件
~/.pam_environment
的登錄方法都會讀取該文件。這涵蓋了當今大多數 Linux 系統。的主要優點
~/.pam_environment
是(啟用時)它在使用者的 shell 啟動之前被讀取,因此無論會話類型、登錄 shell 和其他復雜性如何,它都可以工作。它甚至適用於非互動式登錄,例如su -c somecommand
和ssh somecommand
。的主要限制
~/.pam_environment
是你只能在那裡放置簡單的賦值,而不是複雜的 shell 語法。該文件的語法如下。
- 文件被逐行解析。
- 每行必須具有
VAR=VALUE
VAR 由字母、數字和下劃線組成的形式。另一種形式VAR DEFAULT=value
允許使用${VAR}
語法和特殊變數@{HOME}
和@{SHELL}
.#
開始註釋,它不能出現在值中。- 如果 VALUE 被 包圍
"
,則 VAR 設置為引號之間的字元串。\$
或\@
插入文字$
或@
長行可以通過用 . 轉義換行符來拆分\
。- 如果存在語法錯誤,例如沒有
=
空格或未加引號的空格,則會從環境中刪除該變數。所以從好的方面來說,它
~/.pam_environment
可以在很多情況下工作。不利的一面是,您不能使用命令的輸出(例如,測試目錄或程序是否存在),並且某些字元(#"
、換行符)是不可能或很麻煩的。放什麼
~/.profile
此文件應具有可移植 (POSIX) sh 語法。
[[ … ]]
如果您知道您的系統將這些 shell作為/bin/sh
.該文件可能會被自動化應用程序中的腳本讀取,因此它不應呼叫產生任何輸出的程序或呼叫
exec
. 如果您想在文本模式登錄上執行此操作,請僅對互動式 shell 執行此操作。例子:case $- in *i*) # Display a message if I have new mail if mail -e; then echo 'You have new mail'; fi # If zsh is available, and this looks like a text-mode login, run zsh case "`ps $PPID` " in *" login "*) if type zsh >/dev/null 2>/dev/null; then exec zsh; fi;; esac esac
這是一個使用
/bin/sh
你的登錄 shell 並切換到你最喜歡的 shell 的例子。另請參閱當我的系統管理員拒絕讓我更改它時,我如何使用 bash 作為我的登錄 shell
~/.profile
非圖形登錄何時不讀取?不同的登錄 shell讀取不同的文件。
如果您的登錄 shell 是 bash
Bash 讀取
~/.bash_login
或者~/.bash_profile
如果它們存在而不是~/.profile
.~/.bashrc
即使它是互動式的,bash 也不會在登錄 shell 中讀取。要永遠不必再記住這些怪癖,請~/.bash_profile
使用以下兩行創建一個:. ~/.profile case $- in *i*) . ~/.bashrc;; esac
如果您的登錄 shell 是 zsh
Zsh 讀取
~/.zprofile
and~/.zlogin
,但不是~/.profile
. Zsh 的語法與 sh 不同,但可以~/.profile
在 sh 仿真模式下讀取。您可以將其用於您的~/.zprofile
:emulate sh -c '. ~/.profile'
如果您的登錄外殼是其他外殼
/bin/sh
除了用作您的登錄 shell 和您最喜歡的 shell(如fish)僅用作互動式 shell 之外,您無能為力。這就是我對 zsh 所做的。有關從~/.profile
.遠端命令
在不通過互動式 shell 的情況下呼叫遠端命令時,並非所有 shell 都會讀取啟動文件。
Ksh 讀取由
ENV
變數指定的文件,如果你設法通過它。Bash 讀取
~/.bashrc
它是否不是互動式的 (!) 並且它的父程序被稱為rshd
orsshd
。所以你可以開始你~/.bashrc
的if [[ $- != *i* ]]; then . ~/.profile return fi
Zsh 總是
~/.zshenv
在啟動時讀取。請謹慎使用,因為 zsh 的每個實例都會讀取它,即使它是您設置了其他變數的子 shell。如果 zsh 是您的登錄 shell,並且您想使用它為遠端命令設置變數,請使用保護:在 中設置一些變數~/.profile
,例如MY_ENVIRONMENT_HAS_BEEN_SET=yes
,並在閱讀之前檢查此保護~/.profile
。if [[ -z $MY_ENVIRONMENT_HAS_BEEN_SET ]]; then emulate sh -c '~/.profile'; fi
圖形登錄的案例
許多發行版、顯示管理器和桌面環境都安排執行
~/.profile
,或者通過從啟動腳本中顯式獲取它,或者通過執行登錄 shell。不幸的是,沒有通用的方法來處理
~/.profile
未讀取的發行版/DM/DE 組合。如果您使用由 啟動的傳統會話
~/.xsession
,則應在此處設置環境變數;通過採購~/.profile
(即. ~/.profile
)來做到這一點。請注意,在某些設置中,桌面環境啟動腳本將~/.profile
再次獲取源。