題 選擇.bashrc,.profile,.bash_profile等[複製]


這個問題在這裡已有答案:

這很令人尷尬,但經過多年使用POSIX系統的全職工作,我仍然很難搞清楚shell定制是否應該進入 .bashrc.profile, 或者別的地方。更不用說一些特定於操作系統的配置文件了 .pam_environment

是的,我知道如何解開文檔並了解每個文件何時加載或未加載。我想知道的是,是否有人就如何決定將哪種文件放入給定類型的自定義中的每一個都提出了全面的指導原則。


174
2017-07-29 03:14


起源


這個問題不應該被標記為重複,原因是.profile在添加的問題中不可用。 - Premraj
答: serverfault.com/q/261802/270464 - Premraj


答案:


TL; DR:

  • ~/.bash_profile 應該超級簡單,只需加載 .profile 和 .bashrc (以該順序)

  • ~/.profile 有沒有具體的東西 與bash相關,例如環境變量(PATH 和朋友)

  • ~/.bashrc 在交互式命令行中有你想要的任何東西。 命令提示符, EDITOR 變量,bash別名供我使用

其他幾點說明:

  • 任何應該可用於圖形應用程序或sh(或bash調用為 sh)必須在 ~/.profile

  • ~/.bashrc 不能輸出任何東西

  • 任何只應該用於登錄shell的內容都應該進入 ~/.profile

  • 確保這件事 ~/.bash_login 不存在。


193
2017-07-29 04:27



+1,這允許 ~/.profile 正確設置GDM / LightDM / LXDM等明確運行/ bin / sh的服務的環境。 - grawity
我的 .bashrc 輸出了很多東西,你能評論一下嗎?特別是,我應該在哪裡放置問候語輸出? - Calimo
@Calimo:只在交互模式下輸出內容。您可以使用它進行測試 [[ $- == *i* ]],就是在特殊中尋找'我' $- 變量。當然,它只在編譯bash的系統上首先考慮 .bashrc 在非交互模式下。 (也就是說,Debian但不是Arch。)但是當嘗試連接使用時,它是導致神秘錯誤消息的常見原因 sftp 要么 scp 或類似的工具。 - grawity
現在我必須知道 - 為什麼.bash_login不存在?它有什麼作用? - tedder42
@ tedder42:它的作用相同 .bash_profile 和 .profile。但是bash只能讀取三分之一的第一個。意思是,如果你有一個 .bash_login,然後兩個 .profile 和 .bash_profile 會被神秘地忽略。 - grawity


在過去的幾年裡,我有很多時間浪費,所以我  研究了這個超過10分鐘。我不知道這是否是最好的佈局,它只是恰好在幾乎所有情況下都能正常工作的佈局。

要求:

  • ~/.profile 必須與任何/ bin / sh兼容 - 這包括bash,dash,ksh,以及發行版可能選擇使用的其他內容。

  • 環境變量必須放在由控制台登錄(即“登錄”shell)和圖形登錄(即GDM,LightDM或LXDM等顯示管理器)讀取的文件中。

  • 有一點很重要   ~/.profile 和 ~/.bash_profile。如果後者丟失,bash將很樂意使用前者,並且任何特定於bash的行都可以通過檢查來保護 $BASH 要么 $BASH_VERSION

  • 之間的分離 *profile 和 *rc 是前者用於'登錄'shell,後者用於每次打開終端窗口。但是,“登錄”模式下的bash不會提供 ~/.bashrc因此 ~/.profile 需要手動完成。

簡單 配置將是:

  • 有一個 ~/.profile 設置所有環境變量(除了特定於bash的變量),可能會打印一行或兩行,然後是源 ~/.bashrc 如果由bash運行,則堅持使用與sh兼容的語法。

    出口TZ =“歐洲/巴黎”
    export EDITOR =“vim”
    if [“$ BASH”];然後
        。在〜/ .bashrc
    科幻
    運行時間
    
  • 有一個 ~/.bashrc 執行任何特定於shell的設置,保護檢查 互動模式 避免破壞像 sftp 在Debian上(使用加載選項編譯bash) ~/.bashrc即使是非交互式shell):

    [[$  -  == * i *]] ||返回0
    
    PS1 ='\ h \ w \''
    
    start(){sudo service“$ 1”start; }
    

然而,還存在某些非交互式命令(例如, ssh <host> ls)跳過 ~/.profile,但環境變量對他們非常有用。

  • 某些發行版(例如Debian)使用source選項編譯其bash ~/.bashrc 對於這種非交互式登錄。在這種情況下,我發現移動所有環境變量很有用( export ... 行)到一個單獨的文件, ~/.environ,並從中獲取   .profile 和 .bashrc,有一個警衛,以避免這樣做兩次:

    如果! [“$ PREFIX”];然後 #或$ EDITOR,或$ TZ,或......
        。 〜/ .environ #通常是.environ本身會設置的任何變量
    科幻
    
  • 不幸的是,對於其他發行版(例如Arch),我還沒有找到一個非常好的解決方案。一種可能性是使用(默認啟用)pam_env PAM模塊,將以下內容放入 ~/.pam_environment

    BASH_ENV = /。ENVIRON #不是拼寫錯誤;它需要成為一條道路,但是〜不會起作用
    

    然後,當然,更新 ~/.environ 至 unset BASH_ENV


結論?貝殼是一種痛苦。環境變量很痛苦。特定於分發的編譯時選項是一個 巨大 屁股疼。


46
2017-07-29 15:28



最後一段+1,但我更喜歡採購 .profile 和 .bashrc 從 .bash_profile 並保持 .profile 清潔。 - nyuszika7h
@ nyuszika7h:我的 .profile  很乾淨, 謝謝。 - grawity
注意每次打開窗口時的註釋都是OSX的另一種方式 - Mark
“兩者兼而有之 ~/.profile 和 ~/.bash_profile“:我不屑一顧。看到丹的回答是為什麼。 - rubenvb
@rubenvb你能引用相關部分嗎?我認為只有一個 .profile 守護著 bash - 帶條件的特定零件。 - Kelvin


看看這個 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      |           |      |
+----------------+-----------+-----------+------+

29
2017-07-29 03:39



這很好。重要的是要注意通常 /etc/profile 電話 /etc/bash.bashrc,和 ~/.profile 電話 ~.bashrc。如此有效, /etc/bash.bashrc 和 ~/.bashrc 正在為Interactive Logins執行。 - wisbucky
請注意,某些發行版似乎會覆蓋此方案(帶來奇怪的後果) - 請參閱例如我的bugreport在這裡打開: bugzilla.opensuse.org/show_bug.cgi?id=1078124 - Christian Herenz


我向您提供了我的“全面”指南:

  • 使 .bash_profile 和 .profile 加載 .bashrc 如果存在,使用例如 [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • 把一切都放進去 .bashrc
  • 別擔心
  • 每四年左右,在放棄並回到“不擔心”之前花十分鐘研究這個問題。

編輯:添加恐嚇報價“綜合”,以防萬一有人想要相信它。 ;)


19
2017-07-31 02:45



兩個都有 .bash_profile 和 .profile 有點多餘;你只需要後者。但是你確實需要使它/ bin / sh-proof: if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fi,因為有程序(即gdm / lightdm)從/ bin / sh腳本手動源文件。這也意味著環境保持不變 .bashrc 會無效的。不得不-1,因為你的“綜合”指南不適用於許多系統,因為我已經多次發現了困難的方法。 - grawity
沒問題,我很高興為一個不僅僅是“全面”的答案支付-1,你肯定贏得了這個頭銜。 - Mechanical Fish


我放棄了試圖弄清楚這一個,並製作了一個腳本(~/.shell-setup我從所有其他人那來源。

這種方法需要 ~/.shell-setup 有兩個功能:

  1. 只運行一次,即使重複採購(使用 包括警衛
  2. 不要生成任何不需要的輸出(檢測輸出是否正常)

#1非常標準,儘管在shell腳本中可能沒有太多用處。

#2比較棘手。這是我在bash中使用的內容:

if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
    echo "Hello user!" # ... etc
fi

不幸的是,我不記得我是怎麼想出來的,或者為什麼 檢測交互式shell 還不夠。


0
2017-07-29 03:50





把一切都放進去 .bashrc 然後來源 .bashrc 從 .profile

從bash手冊頁(在OS X 10.9上):

當啟動不是登錄shell的交互式shell時,如果該文件存在,bash將從〜/ .bashrc讀取並執行命令。使用--norc選項可以禁止這一點。 --rcfile文件選項將強制bash從文件而不是〜/ .bashrc讀取和執行命令

上面的文字是為什麼一切都被放入 .bashrc。但是,當您處理登錄shell時,會有一些不同的行為。再次,引用手冊頁:

當bash作為交互式登錄shell或作為具有--login選項的非交互式shell調用時,它首先從文件/ etc / profile中讀取並執行命令(如果該文件存在)。在讀取該文件之後,它按順序查找〜/ .bash_profile,〜/ .bash_login和〜/ .profile,並從存在且可讀的第一個讀取和執行命令。啟動shell以禁止此行為時,可以使用--noprofile選項。

.profile 讀取登錄shell,但是 .bashrc 不是。複製所有內容 .bashrc 很糟糕,所以我們需要把它來源 .profile 為了使行為保持一致。

但是,您不想採購 .bashrc 從 .profile 無條件的。有關其他詳細信息,請參閱註釋和其他答案。


-1



-1, 不要 資源 .bashrc 從 .profile。請參閱@ DanRabinowitz的回答。 - nyuszika7h
至少不是無條件的。 - nyuszika7h
[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrc 將是一個甜蜜的oneliner .profile。 - John WH Smith
@ nyuszika7h,為什麼不呢? 似乎每個人都有 建議這樣做。 - Pacerier