Dockerfiles 中 && 和 `set -ex` 的区别

Bor*_*ard 8 bash docker dockerfile

在 Dockerfiles 中,我已经习惯于看到这种模式(在Docker 的最佳实践中也有说明):

RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*
Run Code Online (Sandbox Code Playgroud)

最近,我经常遇到这样的模式:

RUN set -ex; \
    apt-get update; \
    apt-get install -y curl; \
    rm -rf /var/lib/apt/lists/*
Run Code Online (Sandbox Code Playgroud)

我想知道有什么区别。我试过这个:

$ (echo one; exit 0) && (echo two; exit 0)
one
two

$ (echo one; exit 1) && (echo two; exit 0)
one

$ (echo one; exit 1) ; (echo two; exit 0)
one
two

$ set -ex; (echo one; exit 1) ; (echo two; exit 0)
:bomb: boots me from the session :)
Run Code Online (Sandbox Code Playgroud)

所以似乎有区别,但我不确定它是什么以及它在 Dockerfiles 的上下文中是否重要。

相关(但没有真正回答这个问题):

che*_*ner 7

这不是 Docker 特有的。它只是RUN命令中使用的常规 shell 语法。set -e如果任何命令失败,则导致脚本退出,而&&如果左侧命令没有失败,则仅运行其右侧命令。所以在两者中

set -e
foo
bar
Run Code Online (Sandbox Code Playgroud)

foo && bar
Run Code Online (Sandbox Code Playgroud)

bar只有foo成功才会运行。

因此,如果整个脚本由单个 list 命令组成,... && ... && ...其中一个命令仅在之前的每个命令都成功时运行,则两者是相同的。他们将如何不同的一个例子:

set -e
echo one
false
echo two
echo three
Run Code Online (Sandbox Code Playgroud)

在这里,echo two并且echo three永远不会运行。但在

echo one && false && echo two
echo three
Run Code Online (Sandbox Code Playgroud)

echo three仍然运行,因为只有echo two被“看守”&&它前面。