क्या कोई यह बता सकता है कि सरल उदाहरणों के साथ शेल स्क्रिप्टिंग में निष्पादन कमांड के उपयोग क्या हैं?
क्या कोई यह बता सकता है कि सरल उदाहरणों के साथ शेल स्क्रिप्टिंग में निष्पादन कमांड के उपयोग क्या हैं?
जवाबों:
exec
कर्नेल में निर्मित आदेश दर्पण काम करता है, उनमें से एक परिवार के आधार पर कर रहे हैं execve
, जो आमतौर पर सी से कहा जाता है
exec
fork
एक नई प्रक्रिया के बिना, वर्तमान कार्यक्रम को वर्तमान प्रक्रिया में बदल देता है। यह कुछ ऐसा नहीं है जिसे आप अपने द्वारा लिखी गई प्रत्येक स्क्रिप्ट में उपयोग करेंगे, लेकिन यह अवसर पर काम आता है। यहाँ कुछ परिदृश्य हैं जिनका मैंने उपयोग किया है;
हम चाहते हैं कि उपयोगकर्ता शेल तक पहुंच के बिना एक विशिष्ट एप्लिकेशन प्रोग्राम चलाए। हम साइन-इन प्रोग्राम को / etc / passwd में बदल सकते हैं, लेकिन शायद हम चाहते हैं कि पर्यावरण सेटिंग स्टार्ट-अप फ़ाइलों से उपयोग की जाए। तो, (कहना) .profile
, अंतिम कथन कुछ इस तरह कहता है:
exec appln-program
इसलिए अब वापस जाने के लिए कोई खोल नहीं है। यहां तक कि अगर appln-program
दुर्घटनाओं, अंत उपयोगकर्ता, एक खोल करने के लिए नहीं मिल सकता है, क्योंकि यह वहाँ नहीं है - exec
यह बदल दिया।
हम एक अलग शेल को / etc / passwd में उपयोग करना चाहते हैं। जैसा कि यह प्रतीत हो सकता है, बेवकूफ, कुछ साइटें उपयोगकर्ताओं को अपने साइन-इन शेल को बदलने की अनुमति नहीं देती हैं। एक साइट जो मुझे पता है कि हर किसी के साथ शुरू हुई थी csh
, और सभी ने बस .login
एक कॉल करने के लिए अपने (csh स्टार्ट-अप फ़ाइल) में डाल दिया ksh
। जबकि काम किया, यह एक आवारा csh
प्रक्रिया चल रहा है, और लॉगआउट दो चरण था जो भ्रामक हो सकता है। इसलिए हमने इसे बदल दिया, exec ksh
जिसमें सी-शेल प्रोग्राम को कोर्न शेल के साथ बदल दिया, और सब कुछ सरल बना दिया (इस के साथ अन्य मुद्दे हैं, जैसे कि तथ्य यह है कि ksh
लॉगिन-शेल नहीं है)।
बस प्रक्रियाओं को बचाने के लिए। यदि हम कॉल करते prog1 -> prog2 -> prog3 -> prog4
हैं और कभी वापस नहीं जाते हैं, तो प्रत्येक कॉल को एक निष्पादन करें। यह संसाधनों को बचाता है (बहुत अधिक, व्यक्तिगत रूप से, जब तक दोहराया नहीं जाता है) और शटडाउन को सरल बनाता है।
आपने स्पष्ट रूप से exec
कहीं न कहीं उपयोग किया हुआ देखा है, शायद अगर आपने वह कोड दिखाया है जो आपको गुस्सा दिला रहा है तो हम इसके उपयोग को सही ठहरा सकते हैं।
संपादित करें : मुझे एहसास हुआ कि ऊपर मेरा जवाब अधूरा है। शेल में दो उपयोग हैं exec
जैसे ksh
और bash
- फ़ाइल डिस्क्रिप्टर खोलने के लिए उपयोग किया जाता है। यहाँ कुछ उदाहरण हैं:
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
ध्यान दें कि यहां रिक्ति बहुत महत्वपूर्ण है। यदि आप fd संख्या और पुनर्निर्देशन प्रतीक के बीच एक स्थान रखते हैं तो exec
मूल अर्थ में बदल जाता है:
exec 3 < thisfile # oops, overwrite the current program with command "3"
उदाहरण के लिए , ksh उपयोग पर read -u
या print -u
, इनका उपयोग करने के कई तरीके हैं bash
:
read <&3
echo stuff >&4
exec gunicorn
पर्यवेक्षक को सही पीड देता है।
exec
इसका उपयोग पुनर्निर्देशन के लिए किया जा सकता है:> यदि कमांड निर्दिष्ट नहीं है, तो कोई भी पुनर्निर्देशन वर्तमान शेल में प्रभावी होता है, और रिटर्न की स्थिति 0. है। यदि कोई रीडायरेक्शन त्रुटि है, तो रिटर्न स्थिति 1 है। लेकिन यह कैसे करता है exec
फ़ाइल डिस्क्रिप्टर को बदलने के लिए वास्तव में काम करते हैं? इस कार्य के लिए इस विशेष आदेश को क्यों चुना गया है? (मार्कडाउन अभी असफल हो रहा है?)
exec >.\logfilename.log 2>&1
&>
एक bash
एक्सटेंशन है (देखें man bash
) और आपका उदाहरण इसके बराबर है exec >/var/log/userdata.log 2>&1
। दूसरे शब्दों में यह stdout और stderr को उस फ़ाइल पर पुनर्निर्देशित करता है। जब तक वे रीसेट नहीं हो जाते हैं, तब तक पालन करने वाले कमांड उन पुनर्निर्देशों को प्राप्त करेंगे, लेकिन उन्हें निष्पादित किया जाएगा।
बस एक संक्षिप्त नौसिखिया के अनुकूल संक्षिप्त उत्तर के साथ स्वीकृत उत्तर को बढ़ाने के लिए, आपको शायद ज़रूरत नहीं है exec
।
यदि आप अभी भी यहाँ हैं, तो निम्न चर्चा को उम्मीद है कि क्यों प्रकट करना चाहिए। जब आप दौड़ते हैं, कहते हैं,
sh -c 'command'
आप एक sh
उदाहरण चलाते हैं , फिर command
उस sh
उदाहरण के एक बच्चे के रूप में शुरू करते हैं । जब command
खत्म हो जाता है, तो sh
उदाहरण भी खत्म हो जाता है।
sh -c 'exec command'
एक sh
उदाहरण चलाता है , फिर उस उदाहरण को बाइनरी के साथ बदल देता है , और इसके बजाय उसे चलाता है।sh
command
बेशक, इस सीमित संदर्भ में ये दोनों बेकार हैं; आप बस चाहते हैं
command
कुछ फ्रिंज स्थितियां हैं जहां आप चाहते हैं कि शेल इसकी कॉन्फ़िगरेशन फ़ाइल को पढ़े या किसी तरह से अन्यथा पर्यावरण को चलाने की तैयारी के रूप में सेट करें command
। यह बहुत ही एकमात्र ऐसी स्थिति है जहाँ exec command
उपयोगी है।
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
यह पर्यावरण को तैयार करने के लिए कुछ सामान करता है ताकि इसमें वह शामिल हो जो आवश्यक हो। एक बार ऐसा हो जाने के बाद, sh
उदाहरण की आवश्यकता नहीं रह जाती है, और इसलिए यह एक (मामूली) अनुकूलन है कि sh
उदाहरण को केवल command
प्रक्रिया के साथ बदलें , बजाय sh
इसे एक बाल प्रक्रिया के रूप में चलाएं और इसके लिए प्रतीक्षा करें, फिर जैसे ही यह समाप्त होता है, बाहर निकलें।
इसी तरह, यदि आप शेल स्क्रिप्ट के अंत में किसी भारी-भरकम कमांड के लिए अधिक से अधिक संसाधन मुक्त करना चाहते हैं, तो आप exec
उस कमांड को ऑप्टिमाइज़ेशन के रूप में चाहते हैं ।
अगर कुछ आपको चलाने के लिए मजबूर करता है, sh
लेकिन आप वास्तव में कुछ और चलाना चाहते हैं,exec something else
अवांछित को बदलने के लिए पाठ्यक्रम एक समाधान की है sh
उदाहरण (जैसे उदाहरण के लिए यदि आप वास्तव में अपने स्वयं के spiffy चलाने के लिए करना चाहता था gosh
के बजाय sh
लेकिन तुम्हारा में सूचीबद्ध नहीं है /etc/shells
तो आप कर सकते हैं 'इसे अपने लॉगिन शेल के रूप में निर्दिष्ट करें)।
exec
फ़ाइल डिस्क्रिप्टर में हेरफेर करने का दूसरा उपयोग एक अलग विषय है। स्वीकृत उत्तर अच्छी तरह से कवर करता है; इस स्व-निहित को बनाए रखने के लिए, मैं किसी भी चीज़ के लिए मैनुअल को टाल दूंगा, जहां exec
कमांड नाम के बजाय रीडायरेक्ट होता है।
bush
। बेशक, यह bash
या साथ ही किसी भी लोकप्रिय यूनिक्स शेल पर लागू होता है ; @ नोट के रूप में हालांकि , बैश गुप्त रूप bash -c 'command'
से वास्तव में कर का अनुकूलन करता है exec command
।