Environment-Variables

為什麼沒有這種非互動版本的 bashrc?

  • March 9, 2018

據我了解,守護程序是一個後台程序,但守護程序需要唯一的配置文件來設置環境變數。

例如 Hadoop 守護程序需要hadoop-env.sh來設置環境變數JAVA_HOME,你不能簡單地從~/.bashrc.

原因是因為 daemon 作為後台程序意味著它是非互動式的,而 ~/.bashrc 是意味著只能從互動式會話中使用,以防止alias cp='cp -i'case

最新~/.bashrc的文件頂部有安全防護,不允許非互動式呼叫者,即沒有-i選項將提前返回:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
   *i*) ;;
     *) return;;
esac

這讓我想知道為什麼 bashrc 不將配置文件分成 3 組,例如:

  • ~/.bashrc_interactive
  • ~/.bashrc_non_interactive
  • ~/.bashrc_global #(互動式和非互動式)

因此使用者可以簡單地設置or ,而無需在每個守護程序文件中一遍又一遍地添加此環境變數JAVA_HOME~/.bashrc_non_interactive``~/.bashrc_global

為什麼 bashrc 不以這種方式或任何其他方式支持非互動式,是否有任何理由或限制?還是我誤解了一些概念?

您已經有機會設置BASH_ENV非互動式 shell 腳本在執行之前解析的文件的路徑名。

例如,這允許您在 crontab 中執行

@hourly BASH_ENV="$HOME/.bashrc_non_interactive" "$HOME/bin/mybashscript"

甚至

BASH_ENV="$HOME/.bashrc_non_interactive"

@hourly "$HOME/bin/mybashscript"
@daily  "$HOME/bin/myotherbashscript"

$BASH_ENV通常是空的,但是沒有什麼能阻止你在你的伺服器上全域設置它,將它指向一個/etc文件

if [ -f "$HOME/.bashrc_non_interactive" ]; then
   . "$HOME/.bashrc_non_interactive"
fi

但是,如果腳本需要設置特定的變數,例如JAVA_HOME等,那麼最好BASH_ENV在逐個腳本的基礎上顯式設置,或者從腳本本身顯式獲取相關文件,或者只設置腳本中的變數。將任何非互動式 shell 可能想要在單個文件中使用的所有東西收集起來可能會減慢腳本的速度,並且可能還會用它們不需要的東西污染腳本環境。

文件的概念功能~/.bashrc是正確啟動任何shell,它是:

  • 不是登錄外殼,
  • 互動式外殼。

顯然,這個 shell 腳本的功能是啟動必須在每個 shell 級別更改的環境,例如PS1.

它不適合定義會話或守護程序環境。

還有其他專門用於此類用途的 shell 腳本。

對於互動式會話,bash將按以下順序搜尋啟動文件:

  • /etc/profile
  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile

對於非互動式會話,例如啟動守護程序,bash不使用上述任何文件,而是考慮專用變數BASH_ENV(請參閱Kusalananda 答案)。

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