首頁 > 軟體

為什麼 bash_profile 裡面的設定沒有生效

2020-06-16 16:29:38

最近安裝了 Neovim,並且在 .bash_profile 中設定好了 PATH 變數,奇怪的是,每次在 SSH 用戶端新開啟一個新的 session,登入伺服器進入自己賬號以後,位於.bash_profile 中的 PATH 設定命令沒有生效,導致我無法啟動安裝的 Neovim,每次登入以後,我還必須手動 source 一下 .bash_profile 檔案,然後才能使用 nvim 命令,非常蛋疼。本文就來探索一下原因。

嘗試把 .bash_profile 裡面的設定拷貝到 .bashrc 中,發現登入以後 PATH 變數設定是有效的,可以正常使用 Neovim,這說明 .bash_profile 裡面的設定在登入的時候並未被 source。原因何在?知道了問題癥結以後,很快找到了答案,原來是登入賬戶時使用的 su $USERNAME 指令的問題。如果使用該指令登入自己的賬戶,開啟的 shell 是non-login shell,只有 .bashrc 裡面的設定被 source,所以 .bash_profile 裡面的設定才沒有生效。

login/non-login shell 以及 interactive/non-interactive shell

什麼是 non-login shell?要說清楚這個問題,需要先介紹 shell 的不同模式,為了簡化問題,僅僅針對 Bash shell。shell 分為 login shell 和 non-login shell;也可以分為 interactive shell 和 non-interactive shell.

interactive shell 指的是 shell 可以輸出,也可以接受輸入;non-interactive shell則無法接受使用者輸入,當執行 script 的時候,實際上就是有一個 non-interactive shell 在執行指令碼檔案。login shell 一般指的是使用者通過正常的 ssh 登入到伺服器(輸入使用者名稱和密碼)進入的 shell;如果進入 login shell 以後,再開啟 GUI terminal 或者執行 bash 命令,此時開啟的是 non-login shell。

哪些組態檔被讀取?

採用 interactive login shell 登入的時候,首先讀取並執行 /etc/profile 檔案中命令,然後再依次順序尋找 ~/.bash_profile,~/.bash_login~/.profile 檔案,然後從第一個存在且可讀取的檔案中讀取並執行指令,bash 的 man page 說明如下:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the –login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable

如果是 interactive non-login shell, 啟動時候,首先讀取執行 /etc/bashrc,然後再讀取執行 ~/.bashrc

以上兩種情況是最常見的。

想要在登入賬號的時候確保 .bash_profile 裡面的設定生效,開啟的 shell 必須是login shell。su 命令提供了 -l 選項(等同於 -):

-l Simulate a full login. The environment is discarded except for HOME, SHELL, PATH, TERM, and USER. HOME and SHELL are modified as above. USER is set to the target login. PATH is set to /bin:/usr/bin. TERM is imported from your current environment. The invoked shell is the target login’s, and su will change directory to the target login’s home directory.

所以,登入時候使用 su - USERNAME 即可保證 .bash_profile 裡面的設定生效。


IT145.com E-mail:sddin#qq.com