据我了解,守护进程是后台进程,但守护进程需要唯一的配置文件来设置环境变量。
例如 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
(请参阅善哉答)。