ডকার রানের মাধ্যমে শেল স্ক্রিপ্টে কীভাবে যুক্তিগুলি পাস করবেন


131

আমি ডকার বিশ্বে নতুন। আমাকে একটি শেল স্ক্রিপ্ট চালু করতে হবে যা ডকারের ধারক হয়ে কমান্ড লাইন আর্গুমেন্ট গ্রহণ করে। প্রাক্তন: আমার শেল স্ক্রিপ্টটি দেখতে:

#!bin/bash
echo $1

ডকফেরফাইল দেখতে এরকম দেখাচ্ছে:

FROM ubuntu:14.04
COPY ./file.sh /
CMD /bin/bash file.sh

কনটেইনারটি চালানোর সময় আর্গুমেন্টগুলি কীভাবে পাস করতে হবে তা আমি নিশ্চিত নই

উত্তর:


61

একই ব্যবহার করুন file.sh

#!/bin/bash
echo $1

বিদ্যমান ডকফেরাইল ব্যবহার করে চিত্রটি তৈরি করুন:

docker build -t test .

যুক্তি abcবা xyzঅন্য কিছু দিয়ে চিত্রটি চালান ।

docker run -ti test /file.sh abc

docker run -ti test /file.sh xyz

27
আমি মনে করি ENTRYPOINT হ'ল উপায় যদি আপনি শেষ ব্যবহারকারীকে ফাইল.শ সম্পর্কে সরাসরি জানতে না চান।
গ্রেগইকেন্ডেল

আপনি কীভাবে এই জাতীয় স্ক্রিপ্টটি শুরু করতে পারেন docker run -ti test /file.sh abc। আমি মনে করি যে স্ক্রিপ্টটি চলবে না কারণ এটি হওয়া উচিত docker run -ti test sh /file.sh abc। sh বা / বিন / sh এটি ঠিক চালাবে।
বামসিধর মুগুল্লা

1
অন্য যে কেউ এখানে আসার জন্য। / Usr / bin / env কৌশলটি workচ্ছিক শৈলীর পছন্দ হিসাবে কাজ করে এটির প্রয়োজন হয় না। এছাড়াও #! লাইনটি নির্দেশ করে যে কোন দোভাষীকে ডিফল্ট কেনা উচিত। সুতরাং এটি কেবল স্ক্রিপ্ট কল করে চলতে পারে।
Wheredidthatnamecomefrom

163

এই স্ক্রিপ্ট সহ file.sh

#!/bin/bash
echo Your container args are: "$@"

এবং এই Dockerfile

FROM ubuntu:14.04
COPY ./file.sh /
ENTRYPOINT ["/file.sh"]

তোমার পারা উচিত:

% docker build -t test .
% docker run test hello world
Your container args are: hello world

9
আপনি যেমনটি "" কাছাকাছি "/file.sh" ভুলে যান তবে তা কার্যকর হবে না।
কেভ

6
কোনও কারণে, এটি কাজ করে নাENTRYPOINT ./file.sh
phil294

6
chmod +x file.shএক্সিকিউটেবল পতাকা সেট করতে ভুলবেন না ।
topskip

1
@ কেভ, আপনি কি জানেন যে এটি কেন এমন? ["/file.sh"]এবং /file.shএমনকি বা এর মধ্যে পার্থক্য কী[/file.sh]
নিতজানকিন

1
যথাযথ জসন ফর্ম্যাটিং কেন প্রয়োজন তার জন্য আমার উত্তর দেখুন নিমতাঙ্কিন।
বিএমইচ

60

ডকারের সাথে, এই ধরণের তথ্যটি পাস করার যথাযথ উপায় হল পরিবেশের ভেরিয়েবল through

সুতরাং একই ডকফায়াইলের সাহায্যে স্ক্রিপ্টটি এতে পরিবর্তন করুন

#!/bin/bash
echo $FOO

নির্মাণের পরে, নিম্নলিখিত ডকার কমান্ডটি ব্যবহার করুন:

docker run -e FOO="hello world!" test

20
কেন এটি সবচেয়ে বেশি ভোট দেওয়া উত্তর? এনভ ভার্স হ'ল তথ্য পাস করার অন্য উপায়, তবে ওপি যা জিজ্ঞাসা করছে তা নয়। এবং অবশ্যই কনটেইনারটিতে অর্গগুলি পাস করার জন্য ওপি'র ইচ্ছা সম্পর্কে একেবারেই অযৌক্তিক কিছু নেই।
আংশিক মেঘলা

8
@ পার্টলি ক্লাউডি আমি মনে করি লোকেরা এটি পছন্দ করে কারণ এটি স্পষ্টত ভুল হওয়া সত্ত্বেও "সঠিক" উত্তর দেওয়ার পরিকল্পনা করে purp ডকারের একটি প্রধান নকশার নীতি হ'ল সাধারণ জ্ঞানের তুলনায় ডগমাকে অগ্রাধিকার দেওয়া।
আগস্ট

1
@ অগুরার: এই উত্তরটির উন্নতি করার জন্য, আপনি এই ব্যাখ্যাটি "স্পষ্টতই ভুল" বলে মনে করছেন বলে আপনি ব্যাখ্যা করেছেন?
এমিল স্টেনস্ট্রোম

2
একশ এক্সওয়াই সমস্যা আছে তাই জিজ্ঞাসা করুন। যেহেতু ওপি জানিয়েছে যে তারা ডকারের কাছে নতুন ছিল তাই এটি পুরোপুরি যুক্তিসঙ্গত একটি উত্তর লক্ষ্য অর্জনের প্রস্তাবিত উপায় দেখায়। সুতরাং এটি একটি দুর্দান্ত উত্তর তৈরি।
colm.anseo

1
বিল্ড আরগস এবং সেই সমস্ত গোলমাল হিসাবে ভেরিয়েবলগুলি পাস করার পরিবর্তে কাজটি করার সহজ উপায়। এনভায়রনমেন্ট ভেরিয়েবল হিসাবে সিক্রেট পাস করার জন্য খুব দরকারী।
অরবিন্দ শ্রীধরন

32

এখানে কিছু বিষয়বস্তু রয়েছে:

  1. docker run your_image arg1 arg2এর CMDসাথে মানটি প্রতিস্থাপন করবে arg1 arg2। এটি সিএমডির সম্পূর্ণ প্রতিস্থাপন, এতে আরও মান সংযোজন নয়। এজন্য আপনি প্রায়শই docker run some_image /bin/bashপাত্রে একটি ব্যাশ শেল চালাতে দেখেন ।

  2. আপনি যখন একটি ENTRYPOINT এবং একটি CMD মান উভয়ই সংজ্ঞায়িত করেন, ডকার দু'জনকে একত্রিত করে এবং সেই সংক্ষিপ্ত কমান্ডটি চালিয়ে কনটেইনারটি শুরু করে। সুতরাং আপনি যদি আপনার এন্ট্রিপয়েন্টটিকে এটিরূপে সংজ্ঞায়িত করেন file.sh, আপনি এখন অতিরিক্ত আরোগুলি সহ ধারকটি চালাতে পারেন যা এতে আরোগুলি হিসাবে পাস হবে file.sh

  3. ডকারে এন্ট্রিপয়েন্টস এবং কমান্ডগুলির দুটি সিনট্যাক্স রয়েছে, একটি স্ট্রিং সিনট্যাক্স যা শেল আরম্ভ করবে এবং একটি জেসন সিনট্যাক্স যা একটি এক্সিকিউট সম্পাদন করবে। আইও পুনঃনির্দেশকরণ, একাধিক কমান্ড একসাথে (যেমন জিনিসগুলির সাথে &&) চাপানো , পরিবর্তনশীল প্রতিস্থাপন ইত্যাদির মতো জিনিসগুলি হ্যান্ডেল করতে শেলটি কার্যকর shell একটি ধারক, এটি প্রায়শই কারণ হয়ে থাকে) এবং একসাথে একটি এন্টিপয়েন্ট এবং কমান্ডের সাথে যুক্ত হয়। আপনি যদি আপনার এন্ট্রিপয়েন্টটিকে স্ট্রিং হিসাবে সংজ্ঞায়িত করেন তবে এটি চলবে /bin/sh -c "file.sh", যা একা ভাল। তবে আপনার যদি কমান্ডটি স্ট্রিং হিসাবেও সংজ্ঞায়িত করা থাকে তবে আপনি /bin/sh -c "file.sh" /bin/sh -c "arg1 arg2"আপনার ধারকটির ভিতরে কমান্ডটি চালু করার মতো কিছু দেখতে পাবেন , এটি এত ভাল নয়। এই দুটি বিকল্প কীভাবে ইন্টারঅ্যাক্ট করে সে সম্পর্কে আরও তথ্যের জন্য এখানে টেবিলটি দেখুন

  4. শেল -cবিকল্পটি কেবল একটি একক যুক্তি নেয় takes তার পরে সমস্ত কিছুই সেই একক তর্ক হিসাবে প্রেরণ করা হবে $1, $2তবে আপনি এম্বেড শেল স্ক্রিপ্টে প্রবেশ করবেন না যদি আপনি স্পষ্টভাবে আরজগুলি পাস না করেন। অর্থাৎ /bin/sh -c "file.sh $1 $2" "arg1" "arg2"কাজ করবে, তবে কোনও আরগস না দিয়ে ডাকা /bin/sh -c "file.sh" "arg1" "arg2"হবে না file.sh

সব মিলিয়ে বলা যায়, সাধারণ নকশাটি হ'ল:

FROM ubuntu:14.04
COPY ./file.sh /
RUN chmod 755 /file.sh
# Note the json syntax on this next line is strict, double quotes, and any syntax
# error will result in a shell being used to run the line.
ENTRYPOINT ["file.sh"]

এবং তারপরে আপনি এটি দিয়ে চালান:

docker run your_image arg1 arg2

এখানে এ সম্পর্কে মোটামুটি আরও বিশদ রয়েছে:


1
আমি ইমেজটিতে ["bash", "--login", "-c"]/ ইত্যাদি / প্রোফাইল উত্স পেতে আমার এন্টিপয়েন্টটি সেট করার জন্য পরীক্ষা করেছি , তবে পরে ভেবে ভেবেই ফেলেছিলাম কেন কোনও ডার্ক চালাতে পাস করা শেল স্ক্রিপ্টে কোনও অর্গগুলি দেওয়া হবে না ... আপনার উত্তর সাফ হয়ে গেছে, ধন্যবাদ !
Apteryx

23

আমার কাছে যা আছে তা হ'ল একটি স্ক্রিপ্ট ফাইল যা আসলে জিনিস চালায়। এই স্ক্রিপ্ট ফাইলটি তুলনামূলকভাবে জটিল হতে পারে। আসুন একে "রান_কন্টেইনার" বলি। এই স্ক্রিপ্টটি কমান্ড লাইন থেকে আর্গুমেন্ট গ্রহণ করে:

run_container p1 p2 p3

একটি সাধারণ রান_সামগ্রী হতে পারে:

#!/bin/bash
echo "argc = ${#*}"
echo "argv = ${*}"

আমি যা করতে চাই তা হ'ল "ডকরিং" করার পরে আমি এই কন্টেনারটি ডকার কমান্ড লাইনের প্যারামিটারগুলি দিয়ে এই সূচনাটি শুরু করতে সক্ষম হতে চাই:

docker run image_name p1 p2 p3

এবং প্যারামিটার হিসাবে রান 1 কনটেইনার স্ক্রিপ্টটি পি 1 পি 2 পি 3 দিয়ে চালিত করুন।

এটি আমার সমাধান:

Dockerfile:

FROM docker.io/ubuntu
ADD run_container /
ENTRYPOINT ["/bin/bash", "-c", "/run_container \"$@\"", "--"]

7
ENTRYPOINTঅ্যারেতে তৃতীয় মানটি প্রতিস্থাপন করা "/run_container \"$@\""মানে ফাঁকা স্থান যুক্তিগুলি সঠিকভাবে পরিচালনা করা হয় (যেমন docker run image_name foo 'bar baz' quux)।
ডেভিডচাম্বার

আমার বাশ ফাইলটিতে স্যুইচ / কেস স্টেটমেন্ট যুক্ত করার পরে, ENTRYPOINT ["run_container.sh"] আমার পক্ষে আর কাজ করে না, তবে ENTRYPOINT ["sh", "-c", "run_container.sh"] আমার পরামিতিগুলি আর গ্রহণ করবে না। এই সমাধান (@ ডেভিডচাম্বারের পরামর্শ সহ) আমার পক্ষে কাজ করেছিল।
রমিল্টন

10

আপনি যদি এটি তৈরি করতে চান তবে @ বিল্ড সময়:

CMD /bin/bash /file.sh arg1

আপনি যদি এটি চালাতে চান @ সময় চালিয়ে যান:

ENTRYPOINT ["/bin/bash"]
CMD ["/file.sh", "arg1"]

তারপরে হোস্ট শেলের মধ্যে

docker build -t test .
docker run -i -t test

2
ENTRYPOINTআমি যে রানটাইম চেয়েছিলাম বলে মনে করি সেই ওপিটির পক্ষে একটি ভাল উত্তর, তবে আপনি যদি সত্যিই সময় পরিবর্তনশীল বানাতে চান তবে এই উত্তরটি কেবলমাত্র নষ্ট হয়ে গেছে। ব্যবহারের ARGএবং docker build --build-arg docs.docker.com/engine/reference/builder/#arg
greg.kindel

0

অন্য বিকল্প ...

এই কাজ করতে

docker run -d --rm $IMG_NAME "bash:command1&&command2&&command3"

ডকফাইফিল ইন

ENTRYPOINT ["/entrypoint.sh"]

এন্ট্রিপয়েন্ট.শ

#!/bin/sh

entrypoint_params=$1
printf "==>[entrypoint.sh] %s\n" "entry_point_param is $entrypoint_params"

PARAM1=$(echo $entrypoint_params | cut -d':' -f1) # output is 1 must be 'bash' it     will be tested    
PARAM2=$(echo $entrypoint_params | cut -d':' -f2) # the real command separated by     &&

printf "==>[entrypoint.sh] %s\n" "PARAM1=$PARAM1"
printf "==>[entrypoint.sh] %s\n" "PARAM2=$PARAM2"

if [ "$PARAM1" = "bash" ];
then
    printf "==>[entrypoint.sh] %s\n" "about to running $PARAM2 command"
    echo $PARAM2 | tr '&&' '\n' | while read cmd; do
        $cmd
    done    
fi

কিছু মন্তব্য এবং সীমাবদ্ধতা .... ":" কেটে-ডি ':' পরিবর্তন করতে হবে এবং ডকার রান -d --rm $ IMG_NAME "ব্যাশ: প্রতিধ্বনি $ PATH" এর মতো কমান্ড হোস্টের পরিবর্তে হোস্টের পাথ মানটি প্রদর্শন করবে এক
ওয়াগনারমার্কস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.