एक "निष्पादित" कमांड क्या करता है?


108

मैं बैश कमांड नहीं समझता exec। मैंने इसे स्क्रिप्ट के अंदर उपयोग करके सभी आउटपुट को फ़ाइल में रीडायरेक्ट किया है (जैसा कि इस में देखा गया है )। लेकिन मुझे समझ में नहीं आता है कि यह कैसे काम करता है या यह सामान्य रूप से क्या करता है। मैंने मैन पेज पढ़े हैं लेकिन मैं उन्हें नहीं समझता।


क्या आप वाशर से परिचित हैं एक प्रक्रिया है?
fkraiem

1
@fkraiem तुम्हारा क्या मतलब है?
बेको

सॉरी मेरा मतलब था "क्या"। : पी लेकिन जवाब नहीं लगता है।
fkraiem

लेकिन वास्तव में आपकी स्क्रिप्ट execएक विशेष तरीके से उपयोग की जाती है जिसे बहुत सरल रूप से समझाया जा सकता है, मैं एक उत्तर लिखूंगा।
fkraiem

जवाबों:


88

man bash कहते हैं:

exec [-cl] [-a name] [command [arguments]]
      If command is specified, it replaces the shell.  No new  process
      is  created.  The arguments become the arguments to command.  If
      the -l option is supplied,  the  shell  places  a  dash  at  the
      beginning  of  the  zeroth  argument passed to command.  This is
      what login(1) does.  The -c option causes command to be executed
      with  an empty environment.  If -a is supplied, the shell passes
      name as the zeroth argument to the executed command.  If command
      cannot  be  executed  for  some  reason, a non-interactive shell
      exits, unless the execfail shell option  is  enabled.   In  that
      case,  it returns failure.  An interactive shell returns failure
      if the file cannot be executed.  If command  is  not  specified,
      any  redirections  take  effect  in  the  current shell, and the
      return status is 0.  If there is a redirection error, the return
      status is 1.

अंतिम दो पंक्तियां हैं जो महत्वपूर्ण है: यदि आप execबिना किसी आदेश के स्वयं चलाते हैं , तो यह केवल वर्तमान शेल पर पुनर्निर्देशन को लागू करेगा। आप शायद जानते हैं कि जब आप दौड़ते हैं command > file, तो आपके टर्मिनल के बजाय आउटपुट commandलिखा fileजाता है (इसे रीडायरेक्शन कहा जाता है )। यदि आप exec > fileइसके बजाय चलाते हैं, तो पुनर्निर्देशन पूरे शेल पर लागू होता है: शेल द्वारा निर्मित कोई भी आउटपुट fileआपके टर्मिनल के बजाय लिखा जाता है । उदाहरण के लिए यहाँ

bash-3.2$ bash
bash-3.2$ exec > file
bash-3.2$ date
bash-3.2$ exit
bash-3.2$ cat file
Thu 18 Sep 2014 23:56:25 CEST

मैं पहली बार एक नया bashखोल शुरू करता हूं । फिर, इस नए शेल में मैं चलता हूं exec > file, ताकि सभी आउटपुट को रीडायरेक्ट किया जा सके file। दरअसल, इसके बाद मैं दौड़ता हूं dateलेकिन मुझे कोई आउटपुट नहीं मिलता है, क्योंकि आउटपुट को रीडायरेक्ट किया जाता है file। तब मैं अपने शेल से बाहर निकलता हूं (ताकि रीडायरेक्शन अब लागू न हो) और मैं देखता हूं कि fileवास्तव में dateमेरे द्वारा पहले चलाए गए कमांड का आउटपुट है ।


42
यह केवल आंशिक व्याख्या है। execवर्तमान शेल प्रक्रिया को एक कमांड के साथ बदलने का कार्य भी करता है, ताकि अभिभावक एक तरह से आगे बढ़ें और बच्चे के पास पीआईडी ​​हो। यह केवल पुनर्निर्देशन के लिए नहीं है। कृपया इस जानकारी को जोड़ें
Sergiy Kolodyazhnyy

3
@ SergiyKolodyazhnyy की टिप्पणी के बाद, जो उदाहरण मैंने अभी सामने आया है जिसने मुझे इस पृष्ठ पर ले जाया है वह एक docker-entrypoint.sh है, जहाँ nginx config पर विभिन्न क्रियाओं को करने के बाद, स्क्रिप्ट की अंतिम पंक्ति है exec nginx <various nginx arguments>। इसका मतलब यह है कि नगनेक्स बैश स्क्रिप्ट की सहायता से लेता है और अब नगनेक्स स्क्रिप्ट की नहीं बल्कि कंटेनर की मुख्य रनिंग प्रक्रिया है। मेरा मानना ​​है कि यह सिर्फ स्वच्छता के लिए है, जब तक कि कोई और इसके लिए और अधिक ठोस कारण नहीं जानता है?
ल्यूक ग्रिफिथ्स

1
@ ल्यूक इसे "रैपर स्क्रिप्ट" कहा जाता है। उस का उदाहरण भी है gnome-terminal, जिसमें कम से कम 14.04 में तर्क स्थापित करने के लिए एक आवरण स्क्रिप्ट थी। और यह उनका एकमात्र उद्देश्य है, वास्तव में सेट कला और पर्यावरण। एक और मामला सफाई का होगा - पहले एक प्रक्रिया के पिछले उदाहरण को मारना और नया लॉन्च करना
सर्गी कोलोडियाज़नी

@LukeGriffiths द्वारा दिए गए execउदाहरण के समान एक अन्य उदाहरण nginxवह ~/.vnc/xstartupस्क्रिप्ट है जो vncserverVNC सर्वर प्रक्रिया को कॉन्फ़िगर करने के लिए उपयोग करता है और फिर exec gnome-sessionया exec startkdeइसी तरह।
ट्रेवर बॉयड स्मिथ

@LukeGriffiths, execकंटेनर स्टार्टअप स्क्रिप्ट का मुख्य कारण यह है कि PID 1, कंटेनर का ENTRYPOINT, Docker में एक विशेष महत्व रखता है। यह एक मुख्य प्रक्रिया है जो सिग्नल प्राप्त करती है, और जब यह मौजूद होती है, तो कंटेनर भी बाहर निकल जाता है। कमांड की इस श्रृंखला से बाहर निकालने का execएक तरीका है sh, और डेमॉन को कंटेनर की मुख्य प्रक्रिया बनाना है।
किमी

46

exec दो अलग-अलग व्यवहारों के साथ एक कमांड है, जो इस बात पर निर्भर करता है कि इसके साथ कम से कम एक तर्क का उपयोग किया जाता है, या किसी भी तर्क का उपयोग नहीं किया जाता है।

  • यदि कम से कम एक तर्क पारित किया जाता है, तो पहले वाले को एक कमांड नाम के रूप में लिया जाता है और execइसे एक कमांड के रूप में निष्पादित करने की कोशिश करते हैं, शेष तर्कों को पारित करने के लिए, यदि कोई हो, तो उस कमांड पर और पुनर्निर्देशन का प्रबंधन, यदि कोई हो।

  • यदि पहली दलील के रूप में पारित कमांड मौजूद नहीं है, तो वर्तमान शेल, न केवल निष्पादन कमांड, त्रुटि में बाहर निकलता है।

  • यदि कमांड मौजूद है और निष्पादन योग्य है, तो यह वर्तमान शेल को बदल देता है। इसका मतलब है कि यदि execकोई स्क्रिप्ट दिखाई देती है, तो निष्पादन कॉल का पालन करने वाले निर्देशों को कभी भी निष्पादित नहीं किया जाएगा (जब तक कि execवह सबस्क्रिप्शन में न हो)। execकभी नहीं लौटता। "EXIT" जैसे शेल ट्रैप या तो ट्रिगर नहीं होंगे।

  • यदि कोई तर्क पारित नहीं होता है, तो execइसका उपयोग केवल वर्तमान शेल फ़ाइल डिस्क्रिप्टर को फिर से परिभाषित करने के लिए किया जाता है। execपिछले मामले के विपरीत, शेल जारी रहता है , लेकिन मानक इनपुट, आउटपुट, त्रुटि या जो भी फाइल डिस्क्रिप्टर को पुनर्निर्देशित किया गया है वह प्रभावी हो जाता है।

  • यदि कुछ पुनर्निर्देशन का उपयोग करता है /dev/null, तो इसमें से कोई भी इनपुट ईओएफ वापस कर देगा और इसे करने के लिए किसी भी आउटपुट को छोड़ दिया जाएगा।

  • आप -स्रोत या गंतव्य के रूप में उपयोग करके फ़ाइल डिस्क्रिप्टर को बंद कर सकते हैं, जैसे exec <&-। बाद में पढ़ा या लिखा तो विफल हो जाएगा।

यहाँ दो उदाहरण हैं:

echo foo > /tmp/bar
exec < /tmp/bar # exec has no arguments, will only affect current shell descriptors, here stdin
cat # simple command that read stdin and write it to stdout

यह स्क्रिप्ट कैट कमांड के रूप में "फू" का उत्पादन करेगी, उपयोगकर्ता इनपुट की प्रतीक्षा करने के बजाय जैसा कि सामान्य स्थिति में होता है, उसका इनपुट / tmp / बार फ़ाइल से लिया जाएगा जिसमें foo शामिल है।

echo foo > /tmp/bar
exec wc -c < /tmp/bar # exec has two arguments, the control flow will switch to the wc command
cat

यह स्क्रिप्ट प्रदर्शित होगी 4(बाइट्स की संख्या / tmp / bar) और तुरंत समाप्त हो जाएगी। catआदेश निष्पादित नहीं किया जाएगा।


4
`कुछ पुराने पोस्ट वास्तव में कभी पुराने नहीं होते ... +1।
Cbhihe

3
यदि कुछ पुनर्निर्देशन / dev / null का उपयोग करते हैं, तो संबंधित फ़ाइल विवरणक बंद हो जाता है। नहीं, यह वास्तव में / से पुनर्निर्देशित करता है /dev/null, इसलिए अभी भी सफल लिखता है और ईओएफ लौटाता है। close(2)एफडी पर त्रुटियों को वापस करने के लिए सिस्टम कॉल पढ़ने / लिखने का कारण होगा, और आप exec 2>&-उदाहरण के लिए ऐसा करते हैं ।
पीटर कॉर्डेस

2
इसे स्वयं आज़माएँ exec 3</dev/null; ls -l /proc/self/fd: ध्यान दें कि fd 3 केवल / देव / अशक्त पर खुला पढ़ा जाएगा। फिर इसे फिर से बंद करें exec 3<&-, और आप देख सकते हैं ( ls -l /proc/$$/fdफिर से) कि आपके शेल प्रक्रिया में अब कोई fd 3 नहीं है। (स्टडिन के साथ क्लोजिंग exec <&-स्क्रिप्ट में उपयोगी हो सकती है, लेकिन अंत में यह एक लॉगआउट है।)
पीटर कॉर्ड्स

@PeterCordes आप बिल्कुल सही हैं। उत्तर अपडेट किया गया। धन्यवाद!
जूलियरे

1
यह उत्तर बहुत अच्छा है क्योंकि यह वर्तमान के सबसे अधिक उपयोग किए गए उत्तर के दो उपयोग-मामलों की व्याख्या करता है exec, केवल एक उपयोग-केस के बारे में बात करता है और अन्य उत्तर g_p द्वारा केवल अन्य उपयोग-मामले के बारे में बात करता है। और यह उत्तर इस तरह के जटिल विषय के लिए अच्छा और संक्षिप्त / पठनीय है।
ट्रेवर बॉयड स्मिथ

33

समझने के लिए execआपको पहले समझने की जरूरत है fork। मैं इसे छोटा रखने की कोशिश कर रहा हूं।

  • जब आप सड़क में एक कांटा आते हैं तो आपके पास आम तौर पर दो विकल्प होते हैं। जब वे fork()सिस्टम कॉल मारते हैं तो लिनक्स प्रोग्राम सड़क में इस कांटे तक पहुँचते हैं।

  • सामान्य प्रोग्राम सिस्टम कमांड होते हैं जो आपके सिस्टम पर संकलित रूप में मौजूद होते हैं। जब इस तरह के कार्यक्रम को निष्पादित किया जाता है, तो एक नई प्रक्रिया बनाई जाती है। इस बच्चे की प्रक्रिया में उसके माता-पिता के समान वातावरण है, केवल प्रक्रिया आईडी संख्या अलग है। इस प्रक्रिया को फोर्किंग कहा जाता है ।

  • फोर्किंग एक मौजूदा प्रक्रिया के लिए एक नई शुरुआत करने का एक तरीका प्रदान करता है। हालांकि, ऐसी परिस्थितियां हो सकती हैं जहां एक बच्चे की प्रक्रिया माता-पिता की प्रक्रिया के समान कार्यक्रम का हिस्सा नहीं है। इस मामले execमें प्रयोग किया जाता है। exec एक कार्यक्रम बाइनरी से जानकारी के साथ वर्तमान में चल रही प्रक्रिया की सामग्री को बदल देगा।
  • Forking प्रक्रिया के बाद, नई प्रक्रिया डेटा के साथ बच्चे की प्रक्रिया का पता स्थान अधिलेखित हो जाता है। यह सिस्टम के लिए एक निष्पादन कॉल के माध्यम से किया जाता है।

3
क्या आप समझा सकते हैं कि execस्क्रिप्ट आउटपुट को पुनर्निर्देशित क्यों कर सकते हैं, जैसा कि मैंने पोस्ट किए लिंक में है?
बेको

1
मुझे यह स्पष्ट नहीं मिला "हालांकि, ऐसी परिस्थितियां हो सकती हैं जहां एक बच्चे की प्रक्रिया माता-पिता की प्रक्रिया के समान कार्यक्रम का हिस्सा नहीं है"
cdosborn

6

में bash, यदि आप करते हैं help exec:

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

    Options:
      -a name   pass NAME as the zeroth argument to COMMAND
      -c        execute COMMAND with an empty environment
      -l        place a dash in the zeroth argument to COMMAND

    If the command cannot be executed, a non-interactive shell exits, unless
    the shell option `execfail' is set.

    Exit Status:
    Returns success unless COMMAND is not found or a redirection error occurs.

प्रासंगिक बिट:

If COMMAND is not specified, any redirections take effect in the current shell.

execएक शेल बिल्डिन है , जो कि सिस्टम के execपरिवार के समान शेल है जो G_P बोलता है (और जिसके मैनपेज़ आप पढ़ते हैं)। यदि कोई आदेश निर्दिष्ट नहीं है, तो यह वर्तमान शेल को प्रभावित करने की POSIX अनिवार्य कार्यशीलता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.