我在Dockerfile中有以下命令。每当我创建一个新图像时执行哪个。问题是这个命令失败了,因为我在&
中有一个Xvfb :99 &
。围绕它的好方法是什么?添加引号没有帮助。
RUN set -ex \
&& apt-get update -yqq \
&& apt-get upgrade -yqq \
&& apt-get install -yqq --no-install-recommends \
python3-pip \
python3-requests \
software-properties-common \
python-software-properties \
xvfb \
&& Xvfb :99 & \
&& export DISPLAY=:99
这是确切的错误:/bin/sh: 1: Syntax error: "&&" unexpected
当尝试使用后台进程运行多个命令时,您必须使用&
对命令和()
进行分组。
所以run语句应该如下所示。
RUN set -ex \
&& apt-get update -yqq \
&& apt-get upgrade -yqq \
&& apt-get install -yqq --no-install-recommends \
python3-pip \
python3-requests \
software-properties-common \
python-software-properties \
xvfb \
&& ( Xvfb :99 & ) \
&& export DISPLAY=:99
您看到的错误是因为您在后台运行命令并要求shell根据后台命令的退出状态有条件地运行另一个命令。 shell没有办法在逻辑上做到这一点。你可以在后台进程后删除&&
,但是你留下了更大的问题。
Dockerfile中RUN
命令的结果是pid 1退出后文件系统的更改。在后台使用命令,pid 1(你的shell)将立即退出(当命令运行时)。随着容器的终止,后台进程将被终止。当以pid 1运行的shell退出时,对shell状态的更改(如导出的变量)将丢失。
出于您的目的,您可能希望将后台进程移动到容器入口点的一部分。例如。
RUN apt-get update -yqq \
&& apt-get install -yqq --no-install-recommends \
python3-pip \
python3-requests \
software-properties-common \
python-software-properties \
xvfb \
&& rm -rf /var/lib/apt/lists/*
ENTRPOINT Xvfb :99 & \
export DISPLAY=:99 \
&& some-command-that-needs-a-ui
请注意,我已经删除了apt-get upgrade
,如果您需要在图像中升级包,那么我会使用更新的基本图像。我通常使我的入口点成为shell脚本而不是像这样的长命令,您可能会发现将上面的内容移动到entrypoint.sh更容易,内容如下:
#!/bin/sh
set -ex
Xvfb :99 &
export DISPLAY=:99
some-command-that-needs-a-ui
请注意,在这两个示例中,您都需要指定some-command-that-needs-a-ui
。我不能说那是什么,因为你没有把它包含在问题中。
我会尝试在它前面放一个反斜杠“\”