Fru*_*uit 5 environment-variables history interactive daemon bashrc
据我了解,守护进程是后台进程,但守护进程需要唯一的配置文件来设置环境变量。
例如,Hadoop守护进程需要hadoop-env.sh来设置环境变量JAVA_HOME
,你不能简单地从中获取变量~/.bashrc
。
原因是因为守护进程作为后台进程意味着它是非交互式的,而 ~/.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
Run Code Online (Sandbox Code Playgroud)
这让我想知道为什么 bashrc 不将配置文件分为 3 组,例如:
~/.bashrc_interactive
~/.bashrc_non_interactive
~/.bashrc_global #(交互式和非交互式)
因此用户只需JAVA_HOME
在~/.bashrc_non_interactive
或中设置即可~/.bashrc_global
,无需在每个守护程序文件中一遍又一遍地添加此环境变量。
是否有任何原因或限制 bashrc 不支持这种方式或任何其他方式的非交互式?或者我误解了一些概念?
您已经有机会设置BASH_ENV
非交互式 shell 脚本在运行之前解析的文件的路径名。
例如,这允许您在 crontab 中执行以下操作
@hourly BASH_ENV="$HOME/.bashrc_non_interactive" "$HOME/bin/mybashscript"
Run Code Online (Sandbox Code Playgroud)
甚至
BASH_ENV="$HOME/.bashrc_non_interactive"
@hourly "$HOME/bin/mybashscript"
@daily "$HOME/bin/myotherbashscript"
Run Code Online (Sandbox Code Playgroud)
$BASH_ENV
通常是空的,但是没有什么可以阻止您在服务器上全局设置它,将其指向/etc
该文件下的文件
if [ -f "$HOME/.bashrc_non_interactive" ]; then
. "$HOME/.bashrc_non_interactive"
fi
Run Code Online (Sandbox Code Playgroud)
但是,如果脚本需要设置特定的变量,例如JAVA_HOME
等,那么最好BASH_ENV
在逐个脚本的基础上显式设置,或者从脚本本身显式获取相关文件,或者只设置脚本中的变量。将任何非交互式 shell 可能想要在单个文件中使用的所有内容收集起来可能会减慢脚本速度,并且还可能用脚本不需要的内容污染脚本环境。