नई लाइनों को संरक्षित करते हुए डॉकफाइल में कई लाइनों के साथ कमांड कैसे लिखें?


86

मैं Dockerfile में निम्नलिखित RUN कमांड लिखना चाहता हूं। लेकिन, डॉकटर नई लाइनों को संरक्षित नहीं कर रहा है।

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

मुझे पता है कि \प्रत्येक पंक्ति के अंत में नई रेखा बच जाती है। लेकिन, क्या कोई तरीका है कि मैं नई लाइन को संरक्षित करने वाली कई पंक्तियों को लिख सकूं?


क्या आप नॉन * निक्स प्लेटफॉर्म का उपयोग कर रहे हैं? क्योंकि यह लिनक्स पर मेरे लिए ठीक काम करता है।
उपयोगकर्ता

@user, मैं लिनक्स का उपयोग कर रहा था।
वेंकट जसंवत

जवाबों:


115

आप "ANSI-C उद्धृत" के साथ क्या उपयोग कर सकते हैं $'...'यह मूल रूप से एक ksh93 फीचर था , लेकिन यह अब bash, zsh, mksh, FreeBSD sh और busybox's 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
यह बैश सिंटेक्स है। अधिक जानकारी के लिए यह प्रश्न देखें: stackoverflow.com/a/11966402/1395437
डैनियल ज़ोलनई

13
कृपया, समझाएं कि आप क्या कर रहे हैं, बस एक अपारदर्शी समाधान नहीं छोड़ें
Ldouard Lopez

25
सावधानी का एक शब्द: $' ... \n\ तकनीक उस शेल पर निर्भर करती है जो डॉकटर RUNउपयोग करता है bash। कुछ प्रणालियों (जैसे कि उबंटू) पर शेल का उपयोग करता है /bin/shजो कि अक्सर एक लिंक होता है dashजो कि नहीं है bashऔर $'सिंटैक्स को नहीं समझता है ।
on

2
जैसा कि @ अॉन ने कहा, यह काम नहीं करेगा अगर बैश के अलावा कहीं और चला जाए। ( Oh My Zshदोनों में से कोई भी काम नहीं करता )
राफा

1
@ अच्छी तरह से यह अल्पाइन लाइन में काम करता है (वर्तमान में मैं 3.10.2 पर हूं) जो शेल का उपयोग करता है।
19

53

मैंने इस्तेमाल किया printf। "\ N" का उपयोग करके एक पंक्ति में सभी पाठ लिखना।

निष्पादित:

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

आवेषण:

example
text
here

in.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
पैट्रिक बर्गनर

7

मैंने ऊपर सूचीबद्ध उदाहरणों के संयोजन का उपयोग करके समाप्त किया क्योंकि नई लाइन के \nसाथ काम नहीं किया था echo

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

यह उम्मीद के अनुसार निम्नलिखित उत्पादन करता है:

example
text
here

1
आपका जवाब कैसे कोडोडिया से अलग है?
द गॉडफादर

@ TheGodfather यह एक बहुस्तरीय उदाहरण है। मूल प्रश्न का भी बेहतर उत्तर देता है।
सेर्गेई

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

यह इष्टतम समाधान नहीं हो सकता है क्योंकि यह प्रत्येक आरयूएन कमांड के लिए एक नई परत बनाता है। फिर भी, प्रत्येक परत आपके द्वारा किए गए परिवर्तन जितनी बड़ी होगी, इस मामले में यह बाइट्स के क्रम में है (पहली आरयूएन परत 7-बाइट होनी चाहिए)।

इस समाधान का लाभ यह है कि यह सभी गोले के साथ काम करेगा।


2
संभवतः बेहतर &&कैशिंग उद्देश्यों के लिए इन कमांडों को समाप्‍त करना बेहतर है, लॉगिंग को कम करना और तेजी से Dockerfileनिर्माण समय
जोहानिसबी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.