題 .bashrc和.bash_profile之間的區別


有什麼區別 .bashrc 和 .bash_profile 我應該使用哪一個?


409
2017-09-02 14:40


起源


另見這個類似的問題 ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile - Stefan Lasiewski
如果您想要更完整的解釋也涉及到 .profile,看看這個問題: superuser.com/questions/789448/... - Flimm
這個答案也涵蓋了一些方面 stackoverflow.com/questions/415403/... - Sergey Voronezhskiy


答案:


傳統上,當您登錄Unix系統時,系統會為您啟動一個程序。該程序是一個shell,即一個旨在啟動其他程序的程序。它是一個命令行shell:通過鍵入其名稱來啟動另一個程序。默認shell(Bourne shell)從中讀取命令 ~/.profile 當它作為登錄shell調用時。

Bash是一個類似Bourne的shell。它從中讀取命令 ~/.bash_profile 當它被作為登錄shell調用時,如果該文件不存在¹,它會嘗試讀取 ~/.profile 代替。

您可以隨時直接調用shell,例如在GUI環境中啟動終端仿真器。如果shell不是登錄shell,則不會讀取 ~/.profile。當您將bash作為交互式shell啟動時(即,不運行腳本),它會讀取 ~/.bashrc (除了作為登錄shell調用時,它只讀取 ~/.bash_profile 要么 ~/.profile

因此:

  • ~/.profile 是放置適用於整個會話的內容的地方,例如您希望在登錄時啟動的程序(但不是圖形程序,它們會進入不同的文件)以及環境變量定義。

  • ~/.bashrc 是放置僅適用於bash本身的東西的地方,例如別名和函數定義,shell選項和提示設置。 (你也可以在那裡放置鍵綁定,但對於bash,他們通常會進入 ~/.inputrc。)

  • ~/.bash_profile 可以用來代替 ~/.profile,但它僅由bash讀取,而不是由任何其他shell讀取。 (如果您希望初始化文件在多台計算機上運行,並且您的登錄shell不是所有計算機上的bash,那麼這主要是一個問題。)這是一個合乎邏輯的地方包括 ~/.bashrc 如果shell是交互式的。我推薦以下內容 ~/.bash_profile

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

在現代統一,有一個額外的複雜性相關 ~/.profile。如果您在圖形環境中登錄(即,如果您鍵入密碼的程序在圖形模式下運行),則不會自動獲取讀取的登錄shell ~/.profile。根據圖形登錄程序,在您之後運行的窗口管理器或桌面環境中,以及您的發行版如何配置這些程序,您的 ~/.profile 可能會也可能不會被閱讀。如果不是,通常會有另一個地方可以定義環境變量和程序,以便在您登錄時啟動,但遺憾的是沒有標準位置。

請注意,您可能會在此處看到有關將環境變量定義放入的建議 ~/.bashrc 或者始終在終端中啟動登錄shell。兩者都是壞主意。這兩種想法中最常見的問題是您的環境變量只能在通過終端啟動的程序中設置,而不是在直接使用圖標或菜單或鍵盤快捷鍵啟動的程序中設置。

¹  為完整起見,請按:if .bash_profile 不存在,bash也嘗試 .bash_login在回落之前 .profile。隨意忘記它存在。  


479
2017-09-02 19:23



+1好帖子。還要感謝您添加有關“登錄圖形與登錄shell”的部分...我遇到了問題,我認為〜/ .profile總是會執行圖形/ shell ...但是當用戶登錄時它不會執行通過圖形登錄。謝謝你解決這個謎。 - Trevor Boyd Smith
@Gilles:你能用一些例子更詳細地解釋為什麼在每個終端運行登錄shell都是個壞主意嗎?這只是桌面Linux的一個問題嗎? (我認為在OS X終端上每次運行一個登錄shell,我從來沒有註意到任何副作用(雖然我通常使用iTerm)。但是後來我想不出很多我關心的環境變量終端。(也許HTTP_PROXY?)) - iconoclast
@Brandon如果在每個終端中運行登錄shell,那將覆蓋環境提供的環境變量。在日常情況下,你可以逃脫它,但是當你想在終端中設置不同的變量(比如,嘗試不同版本的程序)時,它遲早會來咬你:運行一個登錄shell將覆蓋您的本地設置。 - Gilles
該聲明 ~/.bash_profile 可以用來代替 ~/.profile,但你還需要包括 ~/.bashrc 如果shell是交互式的。 是誤導,因為這些是正交問題。不管你是否使用 ~/.bash_profile 要么 ~/.profile 你必須包括 ~/.bashrc 在您使用的那個中,如果您希望其中的設置在登錄shell中生效。 - Piotr Dobrogost
@Gilles當然可以,但在答案中表達句子的方式表明需要包含 ~/.bashrc 與選擇有關 ~/.bash_profile 代替 ~/.profile 這不是真的。如果有人包括 ~/.bashrc 在登錄時獲取的任何類型的腳本(這裡也是 ~/.bash_profile 要么 ~/.profile)是因為他想要設置 ~/.bashrc 以與將它們應用於非登錄shell相同的方式應用於登錄shell。 - Piotr Dobrogost


由此 短文

根據bash手冊頁,   執行.bash_profile進行登錄   shell,同時執行.bashrc   交互式非登錄shell。

什麼是登錄或非登錄shell?

當您登錄時(例如:輸入用戶名和   密碼)通過控制台,或者   身體坐在機器上的時候   啟動,或通過ssh遠程啟動:   執行.bash_profile進行配置   初始命令之前的事情   提示。

但是,如果你已經登錄了   你的機器,並打開一個新的終端   gnome或KDE中的window(xterm),   然後.bashrc在之前執行   窗口命令提示符。 .bashrc也是   在啟動新的bash實例時運行   在終端中輸入/ bin / bash。


50
2017-09-02 14:54



輕微更新:'已執行'可能是一個有點誤導性的術語,它們都是來源的。執行的聲音就像它作為腳本運行,fork / exec yadda yadda。它在當前shell的上下文中運行更重要的是,.bashrc運行得更頻繁。它在每個bash腳本運行時運行,如果沒有.bash_profile也運行。此外,根據您設置xterms的方式,您可以創建一個源為.bash_profile的shell - Rich Homolka


回到過去,當偽tty不是偽的,實際上,好,鍵入,並且調製解調器訪問UNIX時,你可以看到每個字母都被打印到你的屏幕上,效率至關重要。為了提高效率,你有一個主登錄窗口的概念,以及你曾經用過的其他窗口。在主窗口中,您需要通知任何新郵件,可能在後台運行其他一些程序。

為了支持這一點,shell發送了一個文件 .profile 特別是'登錄shell'。一旦會話設置,這將是特殊的。 Bash擴展了這一點,首先在.profile之前查看.bash_profile,這樣你就可以把bash只放在那裡(所以他們不會搞砸Bourne shell等等,也看著.profile)。其他shell,非登錄,只會獲取rc文件,.bashrc(或.kshrc等)。

現在這有點過時了。您登錄gui窗口管理器時不會登錄主shell。沒有任何主窗口與任何其他窗口有任何不同。

我的建議 - 不要擔心這種差異,它基於使用unix的舊式。消除文件中的差異。 .bash_profile的全部內容應該是:

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

並將您想要設置的所有內容放在.bashrc中

請記住,.bashrc是所有shell的源,交互式和非交互式。您可以通過將此代碼放在.bashrc頂部附近來短路非交互式shell的源代碼:

[[ $- != *i* ]] && return


34
2017-09-02 18:10



這是一個壞主意,請參閱 我的答案。特別是,您的環境變量將僅在通過終端啟動的程序中設置,而不是在直接使用圖標或菜單或鍵盤快捷鍵啟動的程序中設置。 - Gilles
@Gilles我不明白你為什麼聲稱這個。同 .$HOME/.bashrc 正如Rich所示,設置在 .bashrc 將在登錄shell中提供,因此也可用於桌面環境。例如,在我的Fedora系統上, gnome-session 以...開頭 -$SHELL -c gnome-session所以 .profile 被讀了。 - Mikel
@PiotrDobrogost哦,是的,Rich的答案還有另外一個問題。包含 .bashrc 在 .profile 通常不起作用,因為 .profile 可以執行 /bin/sh 而不是bash(例如,默認情況下在Ubuntu上進行圖形登錄),並且該shell可能不是交互式的(例如,用於圖形登錄)。 - Gilles
@Gilles重新說:“包括.prash中的.bashrc”根本不是所推薦的(實際上恰恰相反)。答案是編輯過的(它沒有出現),或者您的評論與所說的內容不一致。 - michael
一般來說,+1,但我會添加建議“短路...非交互式shell”(“接近.bashrc的頂部: [[ $- != *i* ]] && return“);我確實喜歡我的一些 .bashrc 在發佈時甚至對非交互式shell執行,特別是設置env vars ssh hostname {command},以便遠程命令正確執行(即使shell是非交互式的)。但是後來的其他設置 .bashrc 應該被忽略。我通常檢查TERM =啞和/或未設置,然後提前拯救。 - michael


看看這個 ShreevatsaR出色的博客文章。這是一個摘錄,但是轉到博客文章,它包含對“登錄shell”,流程圖和Zsh類似表等術語的解釋。

對於Bash,它們的工作方式如下。閱讀相應的專欄。執行A,然後是B,然後執行C等.B1,B2,B3表示它只執行找到的第一個文件。

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+

14
2017-07-13 08:53



如果您可以根據提問者的具體需求量身定制答案,而不是在多個問題上發布相同的答案。如果兩個問題的答案完全相同,那麼您應該發布一個答案並投票將其他問題作為原件的副本關閉。 - Mokubai♦
@Mokubai另一個問題已被標記為此問題的副本。 - Flimm
@ElipticalView:設置為什麼都不做,你指的是這一行: [ -z "$PS1" ] && return?我的答案中的表是給出了Bash運行的腳本列表,無論腳本的內容如何,如果腳本本身有行 [ -z "$PS1" ] && return當然那會生效,但我不認為這應該意味著我應該改變一下。 - Flimm


對/ ETC / PROFILE頭部的更好評價

基於Flimm上面的重要答案,我在Debian / etc / profile的頭部對這個新評論進行了修改, (您可能需要為發行版調整它。)

# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found.  (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# |                                 | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# |                                 | login |    non-login     |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   ALL USERS:                    |       |     |            |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV                         |       |     |     A      | not interactive or login
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile                     |   A   |     |            | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc                 |  (A)  |  A  |            | Better PS1 + command-not-found 
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh|  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh       |  (A)  |     |            | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh            |  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   A SPECIFIC USER:              |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile    (bash only)   |   B1  |     |            | (doesn't currently exist) 
# +---------------------------------+-------+-----+------------+
# |~/.bash_login      (bash only)   |   B2  |     |            | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile         (all shells)  |   B3  |     |            | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc          (bash only)   |  (B2) |  B  |            | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout                   |    C  |     |            |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)

這個註釋在每個其他設置文件的頭部引用它:

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

值得注意的是,我認為Debian的/ etc / profile默認來源(包括)/etc/bash.bashrc(當/etc/bash.bashrc存在時)。因此登錄腳本讀取/ etc文件,而非登錄只讀取bash.bashrc。

另外值得注意的是,/ etc / bash.bashrc設置為在不以交互方式運行時不執行任何操作。所以這兩個文件僅用於交互式腳本。


3
2017-10-18 18:13