如何使用“&”创建Dockerfile到RUN命令?

问题描述 投票:0回答:3

我在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

docker dockerfile
3个回答
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

参考:Run multiple commands as bg in Linux


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
投票

我会尝试在它前面放一个反斜杠“\”

© www.soinside.com 2019 - 2024. All rights reserved.