在bash和sh模式下运行的bash中ENV和BASH_ENV的处理

在bash和sh模式下运行的bash中ENV和BASH_ENV的处理

我正在尝试找到一种调用 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下运行我的文件中的命令,并在常规模式下执行相同的操作,但这并没有发生。shBASH_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 ... bashdoes not read /etc/profile.


为什么会有这样的差异呢?这种行为是否与手册相矛盾?

答案1

BASH_ENV仅用于非交互式 bash:

BASH_ENV

如果在调用 Bash 执行 shell 脚本时设置了此变量,则其值将被扩展并用作在执行脚本之前读取的启动文件的名称。看Bash 启动文件

和:

例如,当 Bash 以非交互方式启动时,要运行 shell 脚本,它会BASH_ENV在环境中查找变量,如果变量出现在环境中,则扩展其值,并使用扩展后的值作为要读取和执行的文件的名称。

但事实并非如此ENV如此bash 调用为sh

当作为名为 的交互式 shell 调用时sh,Bash 会查找变量ENV,如果定义了该变量,则扩展其值,并使用扩展后的值作为要读取和执行的文件的名称。

问题中没有任何内容与此相矛盾。

相关内容