Docker CMD与su的干扰:su-exec可以工作,但su不能?

97次阅读
没有评论

问题描述

在这个问题中,用户在Linux Alpine下的一个bash脚本中遇到了一个问题。脚本的第8行是这样的:

exec su-exec "$ZOO_USER" "$0" "$@"

用户想知道是否可以在Ubuntu上避免安装Apache httpd的依赖项su-exec,并使用一些更简单的替代方法。
用户已经尝试了以下方法:

su -c "$0 $@" $ZOO_USER

但是通过Docker的CMD调用时,出现了一些转义/引号错误,导致以下输出:

No passwd entry for user 'start-foreground'

用户想知道与原始的su-exec相比,这两种方法有什么区别?以及如何正确使用su

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

$ZOO_USER作为su的第一个参数,"$@"作为后续参数传递给su
以下是正确的命令:

su -c "$0" "$ZOO_USER" "$@"

选项可以放在用户名之前,最好将它们用双引号括起来,以防止意外输入空格。
你的错误消息表明这是一个参数顺序的问题。

方案2

根据评论,以下方法可能更好:

su -c "$0" "$ZOO_USER" -- "$@"

这样做的好处是可以将su的选项与shell选项(-c)分开。使用--可以将su的选项与要传递给shell的参数分隔开来。
以下是su命令的一部分man页面摘录:

附加参数可以在用户名之后提供,这些参数将传递给用户的登录shell。特别是,-c参数将导致下一个参数被大多数命令解释器视为命令。该命令将由/etc/passwd中为目标用户指定的shell执行。
您可以使用--参数将su选项与传递给shell的参数分隔开来。

以下是busybox文档的摘录:

在评论中,OP问了为什么这在Alpine Linux中不起作用。由于alpine基于busybox,我查阅了busybox文档。根据文档,busybox不支持向su发送额外的参数。

方案3

在Ubuntu中,可以安装gosu,它没有依赖关系。在docker-entrypoint.sh脚本中使用以下命令:

gosu "$ZOO_USER" "$@"

这样可以实现与Alpine中su-exec相同的效果。

请注意,这些解决方案中的任何一个都可能适用,具体取决于您的环境和需求。

参考链接:
su man page
busybox docs
gosu

以上是解决这个问题的几种方法,您可以根据自己的需求选择适合您的方法。

正文完