Docker为什么没有设置$USER环境变量?

15
我正在进行一个简单的Docker构建,其中镜像运行一个脚本,该脚本假定$USER已设置,就像在bash shell中通常设置的那样。
然而,在使用/bin/bash/bin/bash --login时,$USER未设置。最新的ubuntu可以很容易地证明这一点。
$ docker run -t -i ubuntu:latest
root@1dbeaefd6cd4:/# echo $USER

root@1dbeaefd6cd4:/# exit

$ docker run -t -i ubuntu:latest /bin/bash --login
root@d2728a8188a5:/# echo $USER

root@1dbeaefd6cd4:/# exit

然而,如果我在Shell中执行su -l root,那么$USER就会被设置。
root@d2728a8188a5:/# su -l root
root@d2728a8188a5:~# echo $USER
root
root@d2728a8188a5:~# exit

我知道可以在 Dockerfile 中添加 ENV USER=root,但我想避免硬编码这个值。

有人能解释一下为什么会出现这种情况吗?我主要是好奇了解 Docker 启动 bash 时发生了什么。显然它并不完全像一个登录 shell,--login 选项似乎也无法工作。

3个回答

9
唯一记录的环境变量$HOME$HOSTNAME$PATH 和(可能)$TERM。(docker build RUN 步骤在内部执行了相当于 docker run 的操作。)如果您需要设置其他变量,则可以使用 ENV 指令。
通常在 Dockerfile 中,没有必要使路径名或用户名可配置,因为它们存在于与主机分离的隔离空间中。例如,将“应用程序”放在/app中非常常见,尽管这不是标准 FHS 路径。最佳实践是设置一些非 root 用户来运行应用程序,并在 Dockerfile 的后期使用 USER 指令。在所有这些情况下,您都知道实际的用户名;它不是任何类型的参数。

感谢您提供有关Docker环境变量文档的指针,这让我受益匪浅。 - Doug Donohoe
在我的容器中,我配置了一个新用户,当我使用 bash --login 执行时,USER 环境变量被设置。因此,我更新了我的 entrypoint.sh 的 shebang,也加入了 /bin/bash --login,这样就解决了应用程序启动时 USER 环境变量未设置的问题。 - Trevor Boyd Smith

7
根据 https://www.tldp.org/LDP/abs/html/internalvariables.html
变量 $ENV、$LOGNAME、$MAIL、$TERM、$USER 和 $USERNAME 不是 Bash 内置的。但是,在 Bash 或登录启动文件中,这些变量通常被设置为环境变量。
正如 Unix&Linux SE 的这个答案所指出的那样 Who sets $USER and $USERNAME environment variables?:
没有规定。有些 shell(例如 tcsh 或 zsh)设置 $LOGNAME。zsh 设置 $USER。
它可能由一些记录您登录的东西设置,例如 login(由终端上的 getty 调用并且有时由其他类似于 in.rlogind 的东西调用)、cron、su、sudo、sshd、rshd、图形登录管理器或不设置。
在 Docker 容器中的干净环境中,您可能更想依赖 whoami 或 id:
$ docker run --rm -it ubuntu
root@7f6191875c62:/# whoami
root
root@7f6191875c62:/# id
uid=0(root) gid=0(root) groups=0(root)
root@7f6191875c62:/# id -u -n
root

感谢提供背景信息。whoamiid -u -n命令是很好的替代方案 - 感谢列出它们。 - Doug Donohoe

0
尝试运行"/bin/bash -i",这将强制交互模式并执行通常存储环境变量的.profile文件。

谢谢您的建议。但是那样行不通,结果还是一样的。 - Doug Donohoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接