我在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
答案 0 :(得分:6)
当尝试通过后台进程运行多个命令时,必须使用&
将命令和()
分组。
因此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
答案 1 :(得分:1)
您看到的错误是因为您在后台运行命令,并要求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
。我不能说那是什么,因为您没有在问题中包括它。
答案 2 :(得分:-2)
我会尝试在其前面加上反斜杠“ \”