बैश 'बिलिन निष्पादन के लिए केस / व्यावहारिक उदाहरण का उपयोग करें


12

बैश के बिलियन निष्पादन के प्रलेखन से इस पर विचार करें:

निष्पादन एक नई प्रक्रिया बनाए बिना शेल को बदल देता है

कृपया उपयोग मामला / व्यावहारिक उदाहरण प्रदान करें। मुझे समझ नहीं आता कि यह कैसे समझ में आता है।

मैंने googled और I / O पुनर्निर्देशन के बारे में पाया । क्या आप इसे बेहतर तरीके से समझा सकते हैं?


जवाबों:


18

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

#!/bin/sh

if stuff;
    EXTRA_OPTIONS="-x -y -z"
else
    EXTRA_OPTIONS="-a foo"
fi

exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"

ताकि आवरण समाप्त हो जाने के बाद, "वास्तविक" बाइनरी खत्म हो जाए और रैपर स्क्रिप्ट का कोई निशान अब नहीं है जो अस्थायी रूप से प्रक्रिया तालिका में एक ही स्लॉट पर कब्जा कर लिया है। "असली" बाइनरी एक पोते के बजाय इसे लॉन्च करने वाला एक सीधा बच्चा है।

आप अपने प्रश्न में I / O पुनर्निर्देशन का भी उल्लेख करते हैं। यह काफी अलग उपयोग मामला है execऔर इसका किसी अन्य प्रक्रिया के साथ शेल को बदलने से कोई लेना-देना नहीं है। जब execकोई तर्क नहीं है, जैसे:

exec 3>>/tmp/logfile

तब कमांड लाइन पर I / O पुनर्निर्देशन वर्तमान शेल प्रक्रिया में प्रभावी होता है, लेकिन वर्तमान शेल प्रक्रिया चालू रहती है और स्क्रिप्ट में अगले कमांड पर चलती है।


1
आप कह सकते हैं कि दोनों मामले इसी से संबंधित हैं, दोनों के लिए यह execबताता है कि शेल प्रक्रिया नहीं करते हैं (एक कमांड निष्पादित करते हैं या एक पुनर्निर्देशन करते हैं) एक बच्चे की प्रक्रिया में, लेकिन एक ही प्रक्रिया में।
स्टीफन चेज़लस

5

मैंने execएक जावा प्रोग्राम के लिए एक प्रक्रिया आईडी (पीआईडी) प्राप्त करने के लिए शेल बिलिन का उपयोग किया है । अब जावा के अंदर से पीआईडी ​​प्राप्त करने का एक तरीका हो सकता है, लेकिन कई साल पहले, वहाँ नहीं था। एक बार एक प्रक्रिया का अपना PID होता है, तो यह लिख सकता है कि PID फ़ाइल के लिए ( /var/run/फ़ाइल नाम के लिए खोज करें ( '.pid' प्रत्यय के साथ) प्रबंधन कार्यक्रमों को चलाने की प्रक्रिया के PID को जानने के लिए और दूसरा उदाहरण रोकने के लिए। उसी सर्वर के चलने से। यह कुछ इस तरह काम करता है:

exec java -cp=YourServer.jar StartClass -p $$

main()कक्षा की विधि में कोड StartClassतर्क पार्सिंग को हैंडल करता है और अपनी स्वयं की प्रक्रिया आईडी पा सकता है।


2

मज़े के लिए, उपयोगकर्ता प्रक्रिया लेखांकन और सीमाओं के साथ सिस्टम पर पृष्ठभूमि में निम्न प्रोग्राम (अपनी पसंद की कार्यान्वयन भाषा में अनुवादित) चलाएं।

while(true) fork();

अब जब प्रक्रिया तालिका के प्रत्येक स्लॉट जिसे आप उपयोग करने की अनुमति देते हैं, उस रनिंग प्रोग्राम की प्रतियों से भरा है, तो आप इसे कैसे मारना चाहते हैं? लॉन्चिंग किल (1) के लिए एक और प्रोसेस स्लॉट की आवश्यकता होती है, जो आपके पास नहीं हो सकता है। यह यकीन है कि खोल को मारने की कमान के साथ खुद को प्रतिस्थापित करना आसान होगा ...

exec /bin/kill -9 -1

(मान लें कि आपके सिस्टम ने किल (1) / बिन / किल पर मार दिया है।

(नोट: अपने लॉन्चिंग शेल से तब तक लॉग आउट न करें जब तक कि प्रक्रिया की सीमा हमेशा एक नए लॉगिन को उसके शेल के लिए प्रोसेस स्लॉट की अनुमति न दे। यदि आप ऐसा करते हैं, तो इसे साफ करना थोड़ा मुश्किल हो सकता है। मैंने निश्चित रूप से ऐसा नहीं किया था। जल्दी '90 के दशक। नहीं।)


3
(१) यह उत्तर थोड़ा बेहतर होगा यदि आपने वास्तव में वह execकमांड दिखाया जो इस स्थिति में उपयोगी होगा। (२) यह उत्तर कुछ पुरातन है; killआदेश काफी हद तक इस चिंता की वजह से, कई वर्षों के लिए पार्टी में अंतर्निहित आदेश दिया गया है।
जी-मैन का कहना है कि 'मोनिका'

@ जी-मैन: आप समझते हैं कि आपका आइटम (2) इस जवाब को ओपी के लिए सटीक प्रतिक्रिया देता है?
एरिक टावर्स 3

नहीं, मुझे यह समझ में नहीं आता है। कृपया इसे मुझे समझाएं।
जी-मैन का कहना है कि 'मोनिका'

4
मैं तुम्हारा पीछा नहीं कर रहा हूँ। प्रश्न सभी बैश बिलिन कमांड के व्यावहारिक उदाहरणों के लिए नहीं पूछता है ; यह उदाहरण के लिए पूछता है exec- और यह तथ्य कि killएक बिल्टिन वास्तव में execबिल्डिन के साथ कुछ भी करने के लिए नहीं है ।
जी-मैन का कहना है कि 'मोनिका'

1
मैं सिर्फ आपके उत्तर के लिए आपका अपडेट पढ़ता हूं। (1) क्या लगता है? यदि प्रक्रिया तालिका भरी हुई है, तो कमांड प्रतिस्थापन (उदाहरण के लिए `which kill`) या तो काम नहीं कर रहा है। (2) बीटीडब्ल्यू, $(…)फॉर्म के ऊपर फॉर्म की सिफारिश की जाती है `…`। (३) लेकिन निर्देशिका में अनुमान लगाने के बारे में कुछ भी खतरनाक नहीं है। यदि आप गलती से टाइप करते हैं exec /binn/kill, तो आपको बस एक त्रुटि संदेश मिलेगा, और आपका शेल नहीं चलेगा। (४) लेकिन आपको इस बात की चिंता करने की आवश्यकता नहीं है कि सामान्य कमांड की तरह, निर्देशिका killका execउपयोग क्या है  $PATH, इसलिए exec kill …काम करता है (आप /binअपने खोज पथ में हैं)।
जी-मैन का कहना है 'मोनिका'

1
  • यह ब्रूस की प्रक्रिया के पीआईडी ​​को जानने की जरूरत के उदाहरण के समान है:

    (cmdpid = $ BASHPID; (स्लीप 300; किल "$ cmdpid") और लंबे समय तक चलने वाले कमांड को निष्पादित करें )

    जिसमें आप

    1. एक उपधारा (बाहरी (और )) प्रारंभ करें ,
    2. उपखंड के पीआईडी ​​का पता लगाएं। ( $$आपको मुख्य शेल का पीआईडी ​​देगा।)
    3. एक उप-उपखंड को अलग करें जो एक टाइमआउट के बाद आपकी प्रक्रिया को मारता है, और
    4. चरण 1 में आपके द्वारा बनाए गए सबशेल की प्रक्रिया में एक कमांड चलाएं।

    यह चलेगा long-running-command, लेकिन केवल पूर्व-निर्धारित, सीमित समय के लिए। 

  • यह थोड़ा तुच्छ है, लेकिन, यदि आप तय करते हैं कि आप अपने बाकी सत्र के लिए रूट (या कोई अन्य उपयोगकर्ता) बनना चाहते हैं, तो आप कर सकते हैं exec su

    वास्तव में, मैं एक ऐसे परिदृश्य की कल्पना कर सकता हूं जहां यह वास्तव में उपयोगी होगा। मान लीजिए कि आप किसी दूरस्थ सिस्टम में लॉग इन हैं, और, किसी कारण से, कनेक्शन तोड़ने और एक नया कनेक्शन शुरू करने में समस्या है। उदाहरण के लिए, मान लीजिए कि रिमोट सिस्टम में एक फ़ायरवॉल है जो एक शेड्यूल का अनुसरण करता है। आपके द्वारा किए जाने पर आपको कनेक्ट करने की अनुमति दी गई थी, और स्थापित कनेक्शन बंद नहीं हुए हैं, लेकिन वर्तमान समय में, नए कनेक्शन स्वीकार नहीं किए जा रहे हैं।

    आपने वही किया है जो आप करना चाहते थे, और आप लॉगआउट करने के लिए तैयार हैं। आपका दोस्त बॉब आपके साथ कमरे में है, और वह रिमोट सिस्टम पर कुछ काम करना चाहता है - लेकिन वह कनेक्ट नहीं कर पाएगा। इसलिए, आप टाइप करते हैं exec su - bob, और, जब पासवर्ड प्रॉम्प्ट दिखाई देता है, तो वर्कस्टेशन को उसके पास घुमाएं। अब आपके UID के साथ कोई प्रक्रिया नहीं है (जब तक कि आप पृष्ठभूमि में कुछ नहीं चलाते), इसलिए बॉब आपकी फ़ाइलों के साथ गड़बड़ नहीं कर पाएगा। उसने आपके कनेक्शन (आपकी सहमति और सहयोग से) को प्रभावी रूप से लिया होगा।

    टिप्पणियाँ:

    • यदि आपको चलाने की अनुमति नहीं है, तो निश्चित रूप से यह काम नहीं करेगा su
    • यह लॉग इन हो जाएगा, इसलिए आपको किसी को अपना मकसद समझाना पड़ सकता है। चूंकि आप नीति (फ़ायरवॉल शेड्यूल) को दरकिनार कर रहे हैं, आप मुश्किल में पड़ सकते हैं।
    • मैं गारंटी नहीं देता कि यह 100% सुरक्षित है। उदाहरण के लिए, whoशायद अभी भी अपना नाम दिखाएगा। यह बोधगम्य है कि कुछ (बुरी तरह से लिखे गए) कार्यक्रम का उपयोग यह सोचने के लिए किया जाएगा कि बॉब आप हैं, और उसे अपने संसाधनों तक पहुंच प्रदान करें।
    • यदि सिस्टम ऑडिटिंग करता है, तो बॉब के कार्यों का आपके नाम के तहत ऑडिट किया जा सकता है।

ध्यान दें कि अधिकांश गोले में अभ्यास, (a;b)पहले से ही है (a;exec b)क्योंकि गोले एक उपधारा में अंतिम कमांड के लिए कांटा का अनुकूलन करते हैं। केवल अपवाद लगते हैं bashऔर mksh। उपयोग execकरने से इसकी गारंटी मिलती है।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.