Bash

目的-n’$P小號1’−n’$磷小號1’-n ‘$PS1’在 .bashrc

  • August 18, 2018

[ -n "$PS1" ]in的作用是什麼[ -n "$PS1" ] && source ~/.bash_profile;?此行包含在.bashrcdotfiles repo中。

這是檢查外殼是否是互動式的。在這種情況下,僅~/.bash_profile當 shell 是互動式的時才獲取文件。

請參閱“這是 Shell 互動嗎?” 在 bash 手冊中,它引用了該特定的成語。(它還建議通過測試$-特殊變數是否包含i字元來檢查 shell 是否是互動式的,這是解決此問題的更好方法。)

這是做什麼的

這是測試 shell 是否是互動式的一種廣泛使用的方法。請注意,它僅適用於 bash,不適用於其他 shell。所以它可以(如果很傻) for .bashrc,但它不起作用.profile(由 sh 讀取,而 bash 只是 sh 的可能實現之一,而不是最常見的實現)。

為什麼它有效(僅在 bash 中!)

互動式 shell 將shell 變數PS1設置為預設提示字元串。因此,如果 shell 是互動式的,PS1則設置為(除非使用者.bashrc已將其刪除,這在 頂部還不會發生.bashrc,並且您可以認為這是一件愚蠢的事情)。

在 bash 中反之亦然:非互動式 bash 實例PS1在啟動時未設置。請注意,此行為特定於 bash,並且可以說是一個錯誤(為什麼在 bash時bash -c '… do stuff with $var…'不起作用?)。但是所有版本的 bash 直到並包括 4.4(我寫的最新版本)都這樣做。var``PS1

許多系統導出PS1到環境。這是一個壞主意,因為許多不同的 shell 使用PS1但具有不同的語法(例如bash 的提示符轉義與zsh 的提示符轉義完全不同)。但是它已經很普遍了,在實踐中,看到它PS1被設置並不能可靠地表明 shell 是互動式的。shell 可能繼承PS1自環境。

為什麼在這裡(錯誤)使用它

.bashrc是 bash 在互動時在啟動時讀取的文件。一個鮮為人知的事實是 bash 還讀取.bashrc了一個登錄 shell,並且 bash 的啟發式方法得出結論認為這是一個遠端會話(bash 檢查其父級是否為rshdsshd)。在第二種情況下,不太可能PS1在環境中設置,因為還沒有執行點文件。

但是,程式碼使用此資訊的方式適得其反。

  • 如果 shell 是互動式 shell,則它.bash_profile在該 shell 中執行。但是.bash_profile是登錄時腳本。它可能會執行一些旨在每個會話僅執行一次的程序。它可能會覆蓋使用者在執行該 shell 之前故意設置為不同值的一些環境變數。.bash_profile在非登錄 shell 中執行具有破壞性。
  • 如果 shell 是非互動式遠端登錄 shell,則不會載入.bash_profile. 但這是載入.bash_profile可能有用的情況,因為非互動式登錄 shell 不會自動載入/etc/profile~/.profile.

我認為人們這樣做的原因是針對通過 GUI 登錄(一種非常常見的情況)並且將環境變數設置放入.bash_profile而不是.profile. 大多數 GUI 登錄機制呼叫.profile但不呼叫.bash_profile(讀取.bash_profile需要執行 bash 作為會話啟動的一部分,而不是 sh)。使用此配置,當使用者打開終端時,他們將獲得環境變數。但是,使用者不會在 GUI 應用程序中獲得他們的環境變數,這是一個非常常見的混淆來源。這裡的解決方案是使用.profile而不是.bash_profile設置環境變數。在兩者之間添加一座橋樑,.bashrc.bash_profile產生比它解決的問題更多的問題。

該怎麼做

有一種直接、可移植的方式來測試目前 shell 是否是互動式的:測試該選項是否-i被啟用。

case $- in
 *i*) echo "This shell is interactive";;
 *) echo "This shell is not interactive";;
esac

這對於僅在 shell 是非互動式的情況.bashrc下**讀取.profile**很有用——即與程式碼的作用相反!如果 bash 是(非互動式)登錄 shell,請閱讀.profile,如果它是互動式 shell,請不要閱讀。

if [[ $- != *i* && -r ~/.profile ]]; then . ~/.profile; fi

引用自:https://unix.stackexchange.com/questions/462663