我正在尝试找到一种调用 shell 的方法(我需要首先支持 bash 和 posix shell),以确保在开始时执行某些命令(/etc/profile
或~/.profile
任何其他命令)。
当我执行以下操作时:
echo "echo 'test'" > /tmp/file
BASH_ENV=/tmp/file ENV=/tmp/file sh
我得到:
test
$
这很好。检查$SHELL
发现它实际上正在模式bash
下运行sh
。
当我尝试同样的操作时bash
:
echo "echo 'test'" > /tmp/file
BASH_ENV=/tmp/file ENV=/tmp/file bash
我得到:
$
我希望让 bash 在模式ENV
下运行我的文件中的命令,并在常规模式下执行相同的操作,但这并没有发生。sh
BASH_ENV
更广泛的背景是,我正在尝试构建一个可以在其中调用bash
或 的docker 容器sh
,但环境变量确保一开始就在 shell 中执行一些初始化。
Dockerfile
所以重现问题的最小值是:
FROM alpine
RUN apk add bash
RUN echo "echo 'test'" >> /etc/profile
ENV ENV=/etc/profile
ENV BASH_ENV=/etc/profile
同样,构建后,运行 withdocker run ... sh
可以按预期工作,而docker run ... bash
does not read /etc/profile
.
为什么会有这样的差异呢?这种行为是否与手册相矛盾?
答案1
BASH_ENV
仅用于非交互式 bash:
BASH_ENV
如果在调用 Bash 执行 shell 脚本时设置了此变量,则其值将被扩展并用作在执行脚本之前读取的启动文件的名称。看Bash 启动文件。
和:
例如,当 Bash 以非交互方式启动时,要运行 shell 脚本,它会
BASH_ENV
在环境中查找变量,如果变量出现在环境中,则扩展其值,并使用扩展后的值作为要读取和执行的文件的名称。
但事实并非如此ENV
如此bash 调用为sh
:
当作为名为 的交互式 shell 调用时
sh
,Bash 会查找变量ENV
,如果定义了该变量,则扩展其值,并使用扩展后的值作为要读取和执行的文件的名称。
问题中没有任何内容与此相矛盾。