为什么没有这样的非交互式版本的 bashrc?

为什么没有这样的非交互式版本的 bashrc?

据我了解,守护进程是后台进程,但守护进程需要唯一的配置文件来设置环境变量。

例如 Hadoop 守护进程需要hadoop-env.sh要设置环境变量JAVA_HOME,您不能简单地从~/.bashrc.

原因是因为守护进程作为后台进程意味着它是非交互式的,而 ~/.bashrc 意味着仅在交互式会话中使用,以防止alias cp='cp -i'案件

最新的~/.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 #(交互式和非交互式)

因此用户只需JAVA_HOME~/.bashrc_non_interactive或中设置即可~/.bashrc_global,无需在每个守护程序文件中一遍又一遍地添加此环境变量。

是否有任何原因或限制 bashrc 不支持这种方式或任何其他方式的非交互式?或者我误解了一些概念?

答案1

您已经有机会设置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 可能希望在单个文件中使用的内容可能会减慢脚本速度,并且还可能用不需要的内容污染脚本环境。

答案2

文件的概念功能~/.bashrc是正确启动任何 shell,即:

  • 不是登录 shell,
  • 交互式外壳。

显然,这个 shell 脚本的功能是启动必须在 shell 的每个级别更改的环境,例如PS1

它不适合定义会话或守护程序环境。

还有其他专用于此类用途的 shell 脚本。

对于交互式会话,bash将按以下顺序搜索启动文件:

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

对于非交互式会话,例如启动守护程序,bash不使用上述任何文件,但考虑专用变量BASH_ENV(请参阅善哉答)。

相关内容