'docker run'忽略附加到ENTRYPOINT [“ / bin / bash”,“ -c”,“ .foo.sh”]的第一条命令,但不忽略[[bash],“ foo.sh”]的附加命令

时间:2019-07-02 13:19:03

标签: bash docker

我正在尝试运行一个docker映像,该映像执行一个bash脚本并将运行时参数传递给该bash脚本。我发现当我使用推荐的ENTRYPOINT ["/bin/bash", "-c", ". foo.sh"]入口点构建映像时,脚本中没有附加到docker run命令后面的第一个参数,但是当我使用{{ 1}},确实如此。

Shell脚本的玩具版本如下:

ENTRYPOINT ["bash", "foo.sh"]

因此,基本上,脚本需要最多4个命令行参数,每个参数都具有默认值。

我尝试过的原始Dockerfile如下所示:

#!/bin/bash

echo you got "$#" args
ARG1=${1:-foo}
ARG2=${2:-bar}
ARG3=${3:-1}
ARG4=${4:-$(date)}

echo "$ARG1"
echo "$ARG2"
echo "$ARG3"
echo "$ARG4"

并且基于我发现的许多资源,这些资源介绍了如何使用ENTRYPOINT recommended by docker exec 形式正确执行shell脚本。

使用FROM ubuntu COPY foo.sh foo.sh ENTRYPOINT ["/bin/bash", "-c", ". foo.sh"] 构建此图像后,我使用docker build -t foo .运行它,并得到以下输出:

docker run -it foo first second third fourth

因此很显然,附加到you got 3 args second third fourth Tue Jul 2 13:14:52 UTC 2019 命令的第一个参数沿行放置在某处,shell命令提取的唯一参数是第二,第三和第四。

我花了很长时间尝试诊断这个问题,但到目前为止还没有弄清楚为什么会这样。在发现将入口点更改为简单的docker run会产生理想的结果之后,我想出的最好办法是一种变通的解决方法。

我想知道以下几点:1.为什么原始入口点会删除第一个运行时参数? 2.为什么第二个入口点的工作方式与第一个入口点不同?

2 个答案:

答案 0 :(得分:4)

运行bash -c 'something' foo bar baz时,“ foo”成为第零个参数(即$0

也许您需要在其中插入一个虚拟参数

ENTRYPOINT ["/bin/bash", "-c", ". foo.sh", "bash"]

这在bash手册页的-c选项的说明中得到了记录。

答案 1 :(得分:3)

一个Docker容器运行一个进程,具体情况由ENTRYPOINT设置指定;当该进程退出时,容器退出。这意味着您不需要更新周围的Shell环境,因此不需要使用内置的.运行脚本;而且,当您只运行一个简单的命令时,也无需将命令包装在sh -c包装器中。

这会产生类似Dockerfile

FROM ubuntu
COPY foo.sh foo.sh
RUN chmod +x foo.sh # if it’s not executable already
ENTRYPOINT ["./foo.sh"]

这也避免了sh -c使用@GlennJackman的答案中提到的第一个参数的问题。