새 줄을 유지하면서 Dockerfile에서 여러 줄로 명령을 작성하는 방법은 무엇입니까?


84

Dockerfile에 다음 RUN 명령을 작성하고 싶습니다. 그러나 docker는 새로운 라인을 보존하지 않습니다.

RUN echo "[repo] \
name            = YUM Repository \
baseurl         = https://example.com/packages/ \
enabled         = 1 \
gpgcheck        = 0" > /etc/yum.repos.d/Repo.repoxyz

나는 \각 줄의 끝에서 새 줄을 이스케이프 한다는 것을 알고 있습니다. 그러나 새 줄을 유지하면서 여러 줄을 쓸 수있는 방법이 있습니까?


* nix가 아닌 플랫폼을 사용하고 있습니까? 이것은 Linux에서 잘 작동하기 때문입니다.
사용자

@user, 저는 Linux를 사용하고있었습니다.
Venkata Jaswanth

답변:


114

에서 "ANSI-C 인용"을 사용할 수 있습니다 $'...'. 원래 ksh93 기능 이었지만 이제는 bash, zsh, mksh, FreeBSD shbusybox의 ash 에서 사용할 수 있습니다 (그러나 ENABLE_ASH_BASH_COMPAT로 컴파일 된 경우에만).

으로 RUN 사용 /bin/sh기본적으로 셸 당신이 먼저 SHELL 명령을 사용하여 bash는 같은 것으로 스위치에 필요합니다.

다음과 같이 명령을 시작하고 $'로 끝내고 줄 바꿈에 '사용 \n\하십시오.

SHELL ["/bin/bash", "-c"]

RUN echo $'[repo] \n\
name            = YUM Repository \n\
baseurl         = https://example.com/packages/ \n\
enabled         = 1 \n\
gpgcheck        = 0' > /etc/yum.repos.d/Repo.repoxyz

4
bash 구문입니다. 자세한 내용은이 질문을 참조하십시오 : stackoverflow.com/a/11966402/1395437
Daniel Zolnai

13
당신이 무슨 일을하는지 설명해주십시오, 단지 불투명 한 용액을 떨어 뜨리지 않는
에두아르 로페즈

25
주의 사항 :이 $' ... \n\ 기술은 docker가 RUN사용 하는 셸에 따라 다릅니다 bash. 일부 시스템 (예 : Ubuntu)에서 RUN이 사용하는 쉘 /bin/sh은 종종 링크 dash가 아니며 구문을 bash이해하지 못합니다 $'.
Anon

2
@Anon이 말했듯이 bash가 아닌 다른 곳에서 실행되면 작동하지 않습니다. ( Oh My Zsh둘 다 작동하지 않음 )
Rafa

1
@Anon은 쉘을 사용하는 Alpine linux (현재 3.10.2에 있음)에서 잘 작동합니다.
suchoss

52

나는 printf. "\ n"을 사용하여 모든 텍스트를 한 줄에 작성합니다.

실행 중 :

RUN printf 'example \ntext \nhere' >> example.txt

삽입 :

example
text
here

example.txt에서


19

당신이 사용할 수있는:

RUN echo -e "\
[repo] \n\
name            = YUM Repository \n\
baseurl         = https://example.com/packages/ \n\
enabled         = 1 \n\
gpgcheck        = 0\
" > /etc/yum.repos.d/Repo.repoxyz

이렇게하면 파일 내용이 무엇인지 빠르게 확인할 수 있습니다. 모든 줄을로 끝내고 필요할 때 \삽입 해야한다는 것을 알고 있어야 \n합니다.


1
echo -e해석 이 필요 합니다\n
Patrick Bergner

5

새 줄 \n이 .NET에서 작동하지 않았기 때문에 위에 나열된 예제 조합을 사용했습니다 echo.

RUN printf 'example \n\
text \n\
here' >> example.txt

예상대로 다음을 생성합니다.

example
text
here

귀하의 답변은 CTodea의 답변과 어떻게 다른가요?
대부

@TheGodfather 그것은 여러 줄의 예입니다. 원래 질문에도 더 잘 대답합니다.
Sergey

2

도움이 될 수 있습니다 ( https://github.com/jen-soft/pydocker )

[Dockerfile.py]

from pydocker import DockerFile  # sudo pip install -U pydocker

d = DockerFile(base_img='debian:8.2', name='jen-soft/custom-debian:8.2')

d.RUN_bash_script('/opt/set_repo.sh', r'''
cat >/etc/apt/sources.list <<EOL
deb     http://security.debian.org/ jessie/updates main
deb-src http://security.debian.org/ jessie/updates main
EOL
apt-get clean && apt-get update
''')

d.EXPOSE = 80
d.WORKDIR = '/opt'
d.CMD = ["python", "--version"]

# d.generate_files()
d.build_img()

# sudo wget -qO- https://get.docker.com/ | sh

python Dockerfile.py
docker images

-1

RUN을 여러 번 실행하여 파일을 완료 할 수 있습니다.

RUN echo "[repo]" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "name            = YUM Repository" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "baseurl         = https://example.com/packages/" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "enabled         = 1" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "gpgcheck        = 0" >> /etc/yum.repos.d/Repo.repoxyz

이는 모든 RUN 명령에 대해 새 계층을 생성하기 때문에 최적의 솔루션이 아닐 수 있습니다. 그래도 모든 레이어는 변경 한 내용만큼 큽니다.이 경우에는 바이트 순서입니다 (첫 번째 RUN 레이어는 7 바이트 여야 함).

이 솔루션의 장점은 모든 쉘에서 작동한다는 것입니다.


1
&&나은 캐싱, 로깅 감소 및 Dockerfile빌드 시간 단축 을 위해 이러한 명령을 연결 하는 것이 더 낫 습니다
JohannesB
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.