无法在具有 alpine 操作系统的 docker 中使用 echo 配置代码,但可以在 ubuntu 中配置代码

Pad*_*ddy 2 ubuntu docker alpine-linux

我有一个最初从 ubuntu 拉取的 Dockerfile,最近我遇到了更轻量级的 alpine,所以想从它拉取。我尝试构建的部分代码称为Healpix,它依赖于cfitsio。当我最初构建 ubuntu 版本时,我发现了这个 Dockerfile https://github.com/MilesCranmer/dockers/blob/master/dockerfiles/healpix

本质上,问题是在 ubuntu 中有效,但在 alpine 中无效:

RUN echo "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" |
    ./configure && make
Run Code Online (Sandbox Code Playgroud)

我得到的错误是

Something went wrong ...
Quitting configuration script !

./configure: exit: line 162: Illegal number: -1
The command '/bin/sh -c echo     "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" | ./configure     && make' returned a non-zero code: 2
Run Code Online (Sandbox Code Playgroud)

有点令人困惑的是,所讨论的配置脚本不是 162 行长https://sourceforge.net/p/healpix/code/HEAD/tree/branches/branch_v350r1006/configure。我尝试安装 bash 并将脚本更改为该脚本,但这不起作用。

ubuntu Dockerfile

FROM ubuntu
RUN apt-get update && apt-get install -y gcc g++ gfortran make wget
WORKDIR /home
RUN wget \ 
   http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio_latest.tar.gz \
   && tar xzf cfitsio_latest.tar.gz
WORKDIR cfitsio
RUN ./configure --prefix=/usr && make && make install
WORKDIR /home
RUN wget \
   https://sourceforge.net/projects/healpix/files/Healpix_3.50/Healpix_3.50_2018Dec10.tar.gz \
   && tar xzf Healpix*.tar.gz
WORKDIR Healpix_3.50
RUN echo \
    "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" | ./configure \
    && make
Run Code Online (Sandbox Code Playgroud)

高山 Dockerfile

FROM alpine
RUN apk --no-cache add gcc g++ gfortran make wget
WORKDIR /home
RUN wget \ 
   http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio_latest.tar.gz \
   && tar xzf cfitsio_latest.tar.gz
WORKDIR cfitsio
RUN ./configure --prefix=/usr && make && make install
WORKDIR /home
RUN wget \
   https://sourceforge.net/projects/healpix/files/Healpix_3.50/Healpix_3.50_2018Dec10.tar.gz \
   && tar xzf Healpix*.tar.gz
WORKDIR Healpix_3.50
RUN echo \
    "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" | ./configure \
    && make
Run Code Online (Sandbox Code Playgroud)

nor*_*bjd 6

长话短说

在你的中Dockerfile,使用:

RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 和 Alpine 上有相同的行为。

说明

./configure脚本的执行方式为/bin/sh(参见 shebang)。在 Ubuntu 上,/bin/sh是 的链接/bin/dash,而在 Alpine 上,/bin/sh是 的链接/bin/busybox

以下小示例重现了您的问题。

考虑以下./configure脚本:

#!/bin/sh

read -p "1st prompt : " first
read -p "2nd prompt : " second

echo "$first-$second"
Run Code Online (Sandbox Code Playgroud)

在Ubuntu上:

docker run --rm -v $PWD/configure:/configure ubuntu:18.04 \
    /bin/sh -c 'echo "a\nb" | ./configure'
Run Code Online (Sandbox Code Playgroud)

印刷 :

ab

而在阿尔卑斯山上:

docker run --rm -v $PWD/configure:/configure alpine:3.8 \
    /bin/sh -c 'echo "a\nb" | ./configure'
Run Code Online (Sandbox Code Playgroud)

印刷 :

安布-

在 Alpine ( busybox) 上,echoed 字符串 ( a\nb) 被解释为单个参数,而在 Ubuntu ( dash) 上, 则\n用于分隔两个参数。

要在 Alpine 上获得与 Ubuntu 相同的行为,您可以运行:

docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c 'echo "a                   
b                                                 
" | ./configure'
Run Code Online (Sandbox Code Playgroud)

或者 :

docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c \
    'echo -e "a\nb" | ./configure'
Run Code Online (Sandbox Code Playgroud)

(见-e参数echo

这 2 个命令打印:

ab

至于你的Dockerfile,你应该写这样的东西:

RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make
Run Code Online (Sandbox Code Playgroud)

/bin/echo使用而不是echo因为在 Ubuntu 上,echo -e "3\ngfortran\n[...]"将打印-e 3\nngfortran\n[...].

这是因为echo解析了内置的 shell,而/bin/echo明确不是(来源: https: //github.com/moby/moby/issues/8949#issuecomment-61682684)。