আমি যখন আমার শেলটিতে একটি ফাইল কার্যকর করি তখন ঠিক কী ঘটে?


32

সুতরাং, আমি ভেবেছিলাম আমার এ সম্পর্কে ভাল ধারণা আছে তবে কেবল একটি পরীক্ষা চালিয়েছি (এমন কথোপকথনের প্রতিক্রিয়াতে যেখানে আমি কারও সাথে একমত নই) এবং দেখলাম যে আমার বোঝা ত্রুটিযুক্ত ...

যতটা সম্ভব বিশদে আমি যখন আমার শেলটিতে একটি ফাইল কার্যকর করি তখন ঠিক কী ঘটে? আমার অর্থ হ'ল, যদি আমি টাইপ করি: ./somefile some argumentsআমার শেলটিতে এবং টিপুন রিটার্নে (এবং somefileসিডব্লিউডে উপস্থিত রয়েছে, এবং আমি + চালানোর অনুমতিগুলি পড়েছি somefile) তবে হুডের নীচে কী ঘটে?

আমি ভেবেছিলাম উত্তরটি ছিল:

  1. শেলটি একটি execপাথর তৈরি করে, পাথটি অতিক্রম করেsomefile
  2. কার্নেল পরীক্ষা করে ফাইলের ম্যাজিক নম্বরটিsomefile দেখে এটি প্রসেসর হ্যান্ডল করতে পারে এমন কোনও ফর্ম্যাট কিনা তা নির্ধারণ করে
  3. যদি ম্যাজিক নম্বরটি নির্দেশ করে যে ফাইলটি কোনও ফর্ম্যাটে রয়েছে তবে প্রসেসর চালাতে পারে
    1. একটি নতুন প্রক্রিয়া তৈরি করা হয় (প্রক্রিয়া সারণিতে একটি এন্ট্রি সহ)
    2. somefileমেমোরিতে পড়া / ম্যাপ করা হয়। একটি স্ট্যাক তৈরি করা হয় ও মৃত্যুদন্ড এর কোডের এন্ট্রি পয়েন্ট থেকে জাম্প somefileসঙ্গে ARGV(ক প্যারামিটার একটি অ্যারের সক্রিয়া char**, ["some","arguments"])
  4. ম্যাজিক নম্বর হল যদি একটি কুঁড়েঘর তারপর exec()উপরে হিসাবে একটি নতুন প্রক্রিয়া spawns কিন্তু এক্সিকিউটেবল ব্যবহৃত অনুবাদক কুঁড়েঘর দ্বারা সমর্থিত (যেমন হয় /bin/bashবা /bin/perl) এবং somefileপ্রেরণ করাSTDIN
  5. যদি ফাইলটির বৈধ যাদু নম্বর না থাকে তবে "অবৈধ ফাইল (খারাপ যাদু নম্বর): এক্সিকিউট ফর্ম্যাট ত্রুটি" এর মতো একটি ত্রুটি ঘটে

তবে কেউ আমাকে বলেছে যে ফাইলটি যদি সরল পাঠ্য হয় তবে শেলটি কমান্ডগুলি কার্যকর করার চেষ্টা করে (যেন আমি টাইপ করেছি bash somefile )। আমি এটি বিশ্বাস করি নি, তবে আমি এটি চেষ্টা করেছিলাম, এবং এটি সঠিক ছিল। সুতরাং এখানে আসলে কী ঘটে যায় সে সম্পর্কে আমার স্পষ্টত কিছু ভুল ধারণা রয়েছে এবং যান্ত্রিকগুলি বুঝতে চাই।

আমি যখন আমার শেলটিতে একটি ফাইল কার্যকর করি তখন ঠিক কী ঘটে? (যতটা বিস্তারিতভাবে যুক্তিসঙ্গত ...)


বোঝার পূর্ণ গভীরতার জন্য উত্স কোডটি দেখার কোনও সঠিক বিকল্প নেই ।
ওয়াইল্ডকার্ড

1
@ উইল্ডকার্ড আমি এখনই এটি করছি, আসলে :-) আমি যদি পারি তবে আমি আমার নিজের প্রশ্নের উত্তর দেব
জোশ

1
source somefile./somefileযদিও একটি নতুন প্রক্রিয়াটি বন্ধ হয়ে যাওয়ার চেয়ে আলাদা from
ট্রিগার করুন

হ্যাঁ, আমি একমত তবে আমি ভাবিনি যে ফাইলটির যাদু নম্বর না থাকলে ./somefileবাশ কমান্ডগুলি কার্যকর করতে পারে somefile। আমি ভেবেছিলাম এটি কেবল একটি ত্রুটি প্রদর্শন করবে এবং পরিবর্তে এটি কার্যকরভাবে প্রদর্শিত হবেsource somefile
জোশ

আমি আবার ভুল, আমি নিশ্চিত করতে পারি যে যদি somefileএটি একটি পাঠ্য ফাইল হয়, তবে আমি যদি এটি সম্পাদন করার চেষ্টা করি তবে একটি নতুন শেল তৈরি হয়। echo $$যদি আমি বনাম উত্সটি সম্পাদন করি তবে একটি ফাইল আলাদা আচরণ করে।
জোশ

উত্তর:


31

লিনাক্সের "প্রোগ্রামগুলি কীভাবে চালিত হয়" এর চূড়ান্ত উত্তর হ'ল এলডাব্লুএন.এন.টিতে শিরোনামের শিরোনাম, আশ্চর্যজনকভাবে যথেষ্ট, কীভাবে প্রোগ্রামগুলি চালানো হয় এবং কীভাবে প্রোগ্রামগুলি চালিত হয়: ইএলএফ বাইনারি । প্রথম নিবন্ধটি স্ক্রিপ্টগুলি সংক্ষেপে সম্বোধন করে। (যথাযথভাবে উত্তর দেওয়ার উত্সটি সোর্স কোডে বলা হলেও এই নিবন্ধগুলি সোর্স কোডের লিঙ্কগুলি পড়া এবং সরবরাহ করা সহজ))

সামান্য পরীক্ষা-নিরীক্ষা দেখায় যে আপনি এটি বেশ সঠিকভাবে পেয়েছেন এবং শাইবাং ছাড়াই কমান্ডের একটি সহজ তালিকা রয়েছে এমন একটি ফাইলের সম্পাদনকে শেলটি পরিচালনা করা দরকার। Execve (2) র manpage একটি পরীক্ষা প্রোগ্রামের জন্য সোর্স কোড রয়েছে, execve; শেল ছাড়া কী হয় তা দেখতে আমরা এটি ব্যবহার করব। প্রথমে, একটি পরীক্ষামূলক স্ক্রিপ্ট লিখুন testscr1, এতে রয়েছে

#!/bin/sh

pstree

এবং অন্য একটি, testscr2শুধুমাত্র রয়েছে

pstree

এগুলি উভয়কেই কার্যকরযোগ্য করে তুলুন এবং যাচাই করুন যে তারা উভয় শেল থেকে চালাচ্ছেন:

chmod u+x testscr[12]
./testscr1 | less
./testscr2 | less

এখন আবার চেষ্টা করে ব্যবহার করে execve(ধরে নিন যে আপনি এটি বর্তমান ডিরেক্টরিতে তৈরি করেছেন):

./execve ./testscr1
./execve ./testscr2

testscr1এখনও চালায়, কিন্তু testscr2উত্পাদন করে

execve: Exec format error

এটি শেলটি testscr2ভিন্নভাবে পরিচালনা করে তা দেখায় । এটি স্ক্রিপ্ট নিজেই প্রক্রিয়া করে না, এটি এখনও এটি ব্যবহার /bin/shকরে; এটিতে পাইপ testscr2দিয়ে যাচাই করা যেতে পারে less:

./testscr2 | less -ppstree

আমার সিস্টেমে, আমি পেয়েছি

    |-gnome-terminal--+-4*[zsh]
    |                 |-zsh-+-less
    |                 |     `-sh---pstree

আপনি দেখতে পাচ্ছেন, স্ক্রিপ্টটি চালানোর জন্য আমি যে শেলটি ব্যবহার করছিলাম zsh, এটি শুরু হয়েছিল lessএবং দ্বিতীয় শেল, প্লেইন sh( dashআমার সিস্টেমে), যা চলেছিল pstree। ইন zshএই দ্বারা পরিচালিত হয় zexecveSrc/exec.c: শেল ব্যবহারের execve(2)কমান্ড চালানোর চেষ্টা করা, এবং যে যদি ব্যর্থ হলে, এটি ফাইল যদি এটি একটি কুঁড়েঘর আছে দেখতে সার্চ, এটা সেই অনুযায়ী (যা কার্নেল এছাড়াও করেছ হবে) প্রক্রিয়াকরণের, এবং যদি যে ব্যর্থ shহয় যতক্ষণ না এটি ফাইলটি চালানোর চেষ্টা করে , যতক্ষণ না এটি ফাইল থেকে কোনও শূন্য বাইট না পড়ে:

        for (t0 = 0; t0 != ct; t0++)
            if (!execvebuf[t0])
                break;
        if (t0 == ct) {
            argv[-1] = "sh";
            winch_unblock();
            execve("/bin/sh", argv - 1, newenvp);
        }

bashএকই আচরণ রয়েছে, execute_cmd.cসহায়ক মন্তব্যে প্রয়োগ করা হয়েছে (যেমনটি টেলিজিন দ্বারা চিহ্নিত )

একটি সাধারণ কমান্ড কার্যকর করুন যা আশাকরি কোথাও কোনও ডিস্ক ফাইলে সংজ্ঞায়িত।

  1. fork ()
  2. পাইপ সংযোগ করুন
  3. কমান্ডটি দেখুন
  4. পুনর্নির্দেশগুলি করুন
  5. execve ()
  6. যদি execveব্যর্থ হয়, দেখুন ফাইলটিতে এক্সিকিউটেবল মোড সেট রয়েছে কিনা। যদি তা হয়, এবং এটি কোনও ডিরেক্টরি নয়, তবে শেল স্ক্রিপ্ট হিসাবে এর বিষয়বস্তুগুলি কার্যকর করুন।

POSIX নামে পরিচিত ফাংশন একটি সেট, সংজ্ঞায়িত ফাংশন , যা মোড়ানো এবং এই কার্যকারিতা খুব প্রদান করে; দেখতে muru এর বিস্তারিত জানার জন্য উত্তর। লিনাক্সে কমপক্ষে এই ফাংশনগুলি কার্নেল দ্বারা নয়, সি লাইব্রেরি দ্বারা প্রয়োগ করা হয়।exec(3)execve(2)


এটি দুর্দান্ত এবং আমি যে বিশদটি সন্ধান করছিলাম তা রয়েছে, ধন্যবাদ!
জোশ

12

কিছু অংশে, এটি execব্যবহৃত নির্দিষ্ট পরিবার ফাংশনের উপর নির্ভর করে । স্টিফেন কিটexecve যেমন বিশদভাবে দেখিয়েছেন, কেবল সঠিক বাইনারি ফর্ম্যাট বা স্ক্রিপ্টগুলিতে ফাইল চালায় যা সঠিক শেবাং দিয়ে শুরু হয়।

তবে ,execlp এবং execvpআরও এক ধাপ এগিয়ে যান: শেবাংটি সঠিক না হলে ফাইলটি /bin/shলিনাক্সের সাথে কার্যকর করা হয়েছিল। থেকে man 3 exec:

Special semantics for execlp() and execvp()
   The execlp(), execvp(), and execvpe() functions duplicate the actions
   of the shell in searching for an executable file if the specified
   filename does not contain a slash (/) character.
   …

   If the header of a file isn't recognized (the attempted execve(2)
   failed with the error ENOEXEC), these functions will execute the
   shell (/bin/sh) with the path of the file as its first argument.  (If
   this attempt fails, no further searching is done.)

এটি কিছুটা পোসিক্স (জোর খনি) দ্বারা সমর্থিত :

স্ট্যান্ডার্ড বিকাশকারীদের দ্বারা বিভ্রান্ত হওয়ার একটি সম্ভাব্য উত্স কীভাবে কোনও প্রক্রিয়া চিত্রের ফাইলের বিষয়বস্তুগুলি কার্য সম্পাদনকারী পরিবারের আচরণকে প্রভাবিত করে। নীচে গৃহীত পদক্ষেপের বিবরণ দেওয়া হল:

  1. যদি প্রক্রিয়া চিত্র ফাইলটি এই সিস্টেমের জন্য একটি কার্যকর কার্যকর (কার্যকরযোগ্য এবং বৈধ এবং একটি উপযুক্ত ফর্ম্যাট হিসাবে উপযুক্ত আকারে) ফর্ম্যাট হয়, তবে সিস্টেমটি ফাইলটি কার্যকর করে।

  2. যদি প্রক্রিয়া চিত্রের ফাইলে যথাযথ সুযোগ-সুবিধা থাকে এবং একটি ফর্ম্যাটে থাকে যা কার্যকর হয় তবে এই সিস্টেমের জন্য বৈধ নয় (যেমন অন্য কোনও স্থাপত্যের জন্য স্বীকৃত বাইনারি) তবে এটি একটি ত্রুটি এবং ভুলটি [EINVAL] এ সেট করা আছে (পরে দেখুন RATIONALE [EINVAL] এ)।

  3. যদি প্রক্রিয়া চিত্রের ফাইলে যথাযথ সুবিধা থাকে তবে তা অন্যথায় স্বীকৃত হয় না:

    1. যদি এটি এক্সপ্লিটার () বা এক্সিকিউপি () এর জন্য কল হয়, তবে তারা প্রক্রিয়া চিত্র ফাইলটি শেল স্ক্রিপ্ট বলে ধরে নিয়ে একটি কমান্ড ইন্টারপ্রেটারকে অনুরোধ করে।

    2. যদি এটি এক্সপ্লিপ () বা এক্সিকিউপি () চালানোর জন্য কল না হয় তবে একটি ত্রুটি দেখা দেয় এবং এরন [ENOEXEC] এ সেট করা থাকে।

এটি কমান্ড ইন্টারপ্রেটার কীভাবে প্রাপ্ত তা নির্দিষ্ট করে না, তবে ত্রুটিটি দিতে হবে তা নির্দিষ্ট করে না। আমার ধারণা, অতএব, লিনাক্স ডিভস এই জাতীয় ফাইলগুলি চালানোর অনুমতি দেয়/bin/sh (বা এটি ইতিমধ্যে একটি সাধারণ অভ্যাস ছিল এবং তারা কেবল মামলা অনুসরণ করেছে)।

এফডাব্লুআইডাব্লু, ফ্রিবিএসডি ম্যানপেজটিexec(3) একই ধরণের আচরণের কথা উল্লেখ করে:

 Some of these functions have special semantics.

 The functions execlp(), execvp(), and execvP() will duplicate the actions
 of the shell in searching for an executable file if the specified file
 name does not contain a slash ``/'' character. 
 …
 If the header of a file is not recognized (the attempted execve()
 returned ENOEXEC), these functions will execute the shell with the path
 of the file as its first argument.  (If this attempt fails, no further
 searching is done.)

এএএএফআইসিটি, তবে সম্ভবত পরিবেশের উপর সূক্ষ্ম নিয়ন্ত্রণের জন্য কোনও সাধারণ শেল ব্যবহার করে execlpবা execvpসরাসরি হয় না। তারা সবাই একই যুক্তি ব্যবহার করে প্রয়োগ করে execve


3
আমিও লিনাক্স অন্তত যে যোগ করুন, চাই execl, execlp, execle, execv, execvpএবং execvpeসব ফ্রন্ট প্রান্ত হয় execveপ্রাপ্ত syscall; পূর্ববর্তীগুলি সি লাইব্রেরি দ্বারা সরবরাহ করা হয়, কার্নেলটি কেবলমাত্র execve(এবং execveatআজকাল) সম্পর্কে জানে ।
স্টিফেন কিট

যে ব্যাখ্যা @StephenKitt কেন আমি না হয়ে man7.org এর অধ্যায় 2. যারা ফাংশন জন্য র manpage খুঁজে পাইনি
muru

6

এটি স্টিফেন কিট উত্তরের সংযোজন হতে পারে, bashফাইলের উত্স থেকে একটি মন্তব্য হিসাবে execute_cmd.c:

একটি সাধারণ কমান্ড কার্যকর করুন যা আশাকরি কোথাও কোনও ডিস্ক ফাইলে সংজ্ঞায়িত।

1. fork ()
2. connect pipes
3. look up the command
4. do redirections
5. execve ()
6. If the execve failed, see if the file has executable mode set.  

যদি তা হয়, এবং এটি কোনও ডিরেক্টরি নয়, তবে শেল স্ক্রিপ্ট হিসাবে এর বিষয়বস্তুগুলি কার্যকর করুন।


0

এটি শেল স্ক্রিপ্ট হিসাবে কার্যকর হয়, এটি উত্সাহিত হয় না (উদাহরণস্বরূপ, এক্সিকিউটেড ফাইলে সেট করা ভেরিয়েবলগুলি বাইরে প্রভাবিত করে না)। সম্ভবত দু: খের অতীত থেকে অনুসন্ধানযোগ্য, যখন একটি শেল এবং একটি কার্যকরযোগ্য ফর্ম্যাট ছিল। এক্সিকিউটেবল নয়, এটি অবশ্যই শেল স্ক্রিপ্ট হতে হবে।


2
আপনি আমার প্রশ্ন ভুল বুঝেছেন। বিস্তারিত কী হয় ? সর্বনিম্ন, আমার বুঝতে হবে একটি শেবাং পরীক্ষা করে দেখুন, এটি exec()নাকি শেল? আমি উল্লেখযোগ্যভাবে আরও অভ্যন্তরীণ চাই
জোশ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.