我的理解
没有为非交互式/非登录 shell 调用的 rc 文件;例如,由计划任务
(我对此并不确定,因此需要依靠社区的专业知识)非交互式shell 需要
BASH_ENV
设置环境变量,这样就可以将其设置为特定的 rc 文件(例如BASH_ENV=$HOME/.bash_profile
)
希望
我不确定有多少可用的 rc 文件,所以很好奇是否有我不熟悉的文件。希望找到一个满足以下条件的 rc 文件:
- 无论交互/登录模式如何都会被调用,因此可以在一个地方设置全局 shell 环境变量
- 性能更像 csh/tcsh
答案1
对您的具体问题的回答是,通常只加载/etc/bash.bashrc
(或 )。/etc/bashrc
似乎有几种方法可以解决这个问题,不幸的是,大多数都是权宜之计。没有特定的优先顺序:
伪造登录
登录运行/etc/profile
,通常你可以将自定义脚本放在/etc/profile.d/*.sh
将其包装在 bash 登录中
有时最简单的方法是触发登录,即
echo "do whatever $PATH $BASH $PS1 $0"
变成
bash -lc 'echo "do whatever $PATH $BASH $PS1 $0"'
手动加载配置文件
执行登录操作,手动加载配置文件
source /etc/profile;echo "do whatever $PATH $BASH $PS1 $0"
编辑全局环境变量
对于简单变量,您可以添加以/etc/environment
查看Ubuntu 系统范围的环境变量但变量扩展不是工作
THING_HOME="/opt/thing"
PATH="$PATH:/opt/thing" # this will NOT work
对于 PATH 你可以附加到它例如sudo sed -i 's#PATH=\"[^\"]*#&:/opt/thing#' /etc/environment
编辑所有 bash shell
您可以添加到/etc/bash.bashrc
(或 /etc/bashrc
)然而如果是非交互式的,这通常会提前退出,因此您需要在之前破解您的添加内容:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
不要做以下任何一件事
- 如果你尝试向 PATH 添加某些内容,请考虑使用符号链接
- 考虑让你的程序/脚本修改自己的环境
- Systemd
EnvironmentFile
有Environment
systemctl edit --full cron.service
我很想知道是否有其他人有更好的解决方法!
答案2
最近,我想诱导bash
它表现得好像某个特定的源文件对它来说是“原生的”,而不管执行上下文如何。
这样我就可以形成一种“方言”,bash
可以从#!
(“shebang”)运行,也可以交互运行。我还没有测试过它作为登录 shell。
最后的结果非常简单:
- 需要获取脚本的单独
bash
文件 envsubst
将此文件的绝对位置放入复制到以下目录中的运行器中PATH
:
SOURCE="$(realpath special_bash)" envsubst <./special_bash_runner_source >/usr/bin/special_bash
- 跑步者本身:
#!/bin/sh
# optional check to ensure bash is not called with two `--rcfile` or `--init-file`:
# echo "$@" | grep -F -e rcfile -e init-file >/dev/null && echo '--rcfile and --init-file parameters not supported' 1>&2 && exit 99
ENV="$SOURCE" BASH_ENV="$SOURCE" bash --rcfile "$SOURCE" "$@"
然后,为了防止嵌套执行(考虑到我的脚本对bash
执行环境应用了破坏性转换):
! [ /bin/bash = "$SHELL ] && echo "runner only works in a bash shell, exiting" 1>&2 && exit 1
SHELL=/usr/bin/special_bash
(这个也许需要多一点的爱。)
最重要的是,交互式会话检测:
[ -t 0 ] && [ -t 1 ] && set +e
(我set -e
默认在脚本中使用,但这对于交互式会话来说太不切实际了。)
通过这个我可以做到两件事:
$ special_bash
... 进入交互式special_bash
会话,我还可以这样做:
#/usr/bin/env special_bash
iffffffffffffff testerontario -z ""; and_only_then
... <more silly bash dialect>
fffffffffffffff