无法使用 alpine os 在 docker 中使用 echo 配置代码,但在 ubuntu 中可以
Cannot configure code with echo in docker with alpine os but can in ubuntu
我有一个 Dockerfile,它最初是从 ubuntu 中提取的,我最近遇到了更轻量级的 alpine,所以想从中提取。我尝试构建的部分代码称为 Healpix which depends on cfitsio. When I originally built the ubuntu version I found this 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
我得到的错误是
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
有点令人困惑的是,所讨论的配置脚本不是 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
高山 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
TL;DR
在您的 Dockerfile
中,使用:
RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make
在 Ubuntu 和 Alpine 上具有相同的行为。
解释
./configure
脚本使用 /bin/sh
执行(参见 shebang)。在 Ubuntu 上,/bin/sh
是 link 到 /bin/dash
,而在 Alpine 上,/bin/sh
是 link 到 /bin/busybox
。
下面的小例子重现了您的问题。
考虑以下 ./configure
脚本:
#!/bin/sh
read -p "1st prompt : " first
read -p "2nd prompt : " second
echo "$first-$second"
在 Ubuntu 上:
docker run --rm -v $PWD/configure:/configure ubuntu:18.04 \
/bin/sh -c 'echo "a\nb" | ./configure'
打印:
a-b
同时,在高山上:
docker run --rm -v $PWD/configure:/configure alpine:3.8 \
/bin/sh -c 'echo "a\nb" | ./configure'
打印:
anb-
在 Alpine (busybox
) 上,echo
ed 字符串 (a\nb
) 被解释为单个参数,而在 Ubuntu (dash
), \n
用于分隔两个参数。
要在 Alpine 上获得与 Ubuntu 相同的行为,您可以 运行 :
docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c 'echo "a
b
" | ./configure'
或:
docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c \
'echo -e "a\nb" | ./configure'
(见echo
的-e
参数)
这 2 个命令打印:
a-b
至于你的Dockerfile
,你应该这样写:
RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make
使用 /bin/echo
而不是 echo
因为在 Ubuntu 上,echo -e "3\ngfortran\n[...]"
将打印 -e 3\nngfortran\n[...]
.
This is because echo
is parsed a shell built-in, while /bin/echo
is explicitly not (source : https://github.com/moby/moby/issues/8949#issuecomment-61682684).
我有一个 Dockerfile,它最初是从 ubuntu 中提取的,我最近遇到了更轻量级的 alpine,所以想从中提取。我尝试构建的部分代码称为 Healpix which depends on cfitsio. When I originally built the ubuntu version I found this 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
我得到的错误是
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
有点令人困惑的是,所讨论的配置脚本不是 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
高山 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
TL;DR
在您的 Dockerfile
中,使用:
RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make
在 Ubuntu 和 Alpine 上具有相同的行为。
解释
./configure
脚本使用 /bin/sh
执行(参见 shebang)。在 Ubuntu 上,/bin/sh
是 link 到 /bin/dash
,而在 Alpine 上,/bin/sh
是 link 到 /bin/busybox
。
下面的小例子重现了您的问题。
考虑以下 ./configure
脚本:
#!/bin/sh
read -p "1st prompt : " first
read -p "2nd prompt : " second
echo "$first-$second"
在 Ubuntu 上:
docker run --rm -v $PWD/configure:/configure ubuntu:18.04 \
/bin/sh -c 'echo "a\nb" | ./configure'
打印:
a-b
同时,在高山上:
docker run --rm -v $PWD/configure:/configure alpine:3.8 \
/bin/sh -c 'echo "a\nb" | ./configure'
打印:
anb-
在 Alpine (busybox
) 上,echo
ed 字符串 (a\nb
) 被解释为单个参数,而在 Ubuntu (dash
), \n
用于分隔两个参数。
要在 Alpine 上获得与 Ubuntu 相同的行为,您可以 运行 :
docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c 'echo "a
b
" | ./configure'
或:
docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c \
'echo -e "a\nb" | ./configure'
(见echo
的-e
参数)
这 2 个命令打印:
a-b
至于你的Dockerfile
,你应该这样写:
RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make
使用 /bin/echo
而不是 echo
因为在 Ubuntu 上,echo -e "3\ngfortran\n[...]"
将打印 -e 3\nngfortran\n[...]
.
This is because
echo
is parsed a shell built-in, while/bin/echo
is explicitly not (source : https://github.com/moby/moby/issues/8949#issuecomment-61682684).