2011-10-19 11 views
7

मैंने के साथ $! के साथ गलती से एक बैश स्क्रिप्ट शुरू की और 0 बहुत ही अजीब व्यवहार प्राप्त किया। मैं यह पता लगाने की कोशिश कर रहा हूं कि क्या हुआ।

आप इस स्क्रिप्ट का प्रयास करें:

$!/bin/bash 
echo Hello world! 

आप निम्नलिखित व्यवहार मिल जाएगा:

  1. एक नया बैश खोल पैदा की:

    $ chmod +x hello 
    $ ./hello 
    [nothing happens, get prompt back] 
    $ exit 
    exit 
    Hello world! 
    $ 
    

    तो यह इस तरह हुआ लग रहा है।

  2. बाहर निकलने पर, शेष स्क्रिप्ट निष्पादित की गई।

क्या हो रहा है? सब कुछ कैसे हो रहा है? #! के बिना, स्क्रिप्ट को समझने के लिए खोल को bash का उपयोग करने के बारे में कैसे पता है?

स्पष्ट रूप से यह "मेरी समस्या का समाधान" प्रश्न के बजाय "मेरी जिज्ञासा को पूरा करें" है। Googling अधिक पैदा नहीं करता है, शायद #! और $! प्रश्नों में Google-Bot खुश नहीं करते हैं।

उत्तर

9

$ कुछ एक पैरामीटर ("चर") विस्तार है, लेकिन विशेष रूप से रिटर्न एक मूल्य है कि अपनी स्क्रिप्ट में सेट नहीं है में $! है, इसलिए यह शून्य लंबाई स्ट्रिंग के रूप में फैलता है।

/bin/bash 
echo Hello world! 

shebang magic number यूनिक्स के एक पुराने सुविधा है, लेकिन खोल भी पुराना है:

इसलिए अपनी स्क्रिप्ट यह है कि आप सही हैं, के बराबर। निष्पादित बिट सेट के साथ एक टेक्स्ट फ़ाइल जो कर्नेल निष्पादित नहीं कर सकती है (क्योंकि यह वास्तव में संकलित नहीं है) को सबहेल द्वारा निष्पादित किया जाता है। यही है, खोल जानबूझकर एक और खोल चलाता है और पथनाम को पैरामीटर के रूप में पास करता है। शेब स्क्रिप्ट के रूप में लिखे गए आदेशों को शेबैंग का आविष्कार करने से पहले निष्पादित किया गया था, और यह अभी भी कोड में है।

3

@ डिजिटलरॉस के उत्तर पर थोड़ा सा विस्तार:। पहली पंक्ति पर कोई #! साथ

एक निष्पादन स्क्रिप्ट /bin/sh द्वारा निष्पादित किया जाता है - भले ही आप इसे bash (या tcsh) से निष्पादित करें। यह खोल कार्यक्षमता नहीं है, यह कर्नेल में है।

तो जब आप अपनी स्क्रिप्ट निष्पादित, यह /bin/sh द्वारा मार डाला गया था (जिसका अर्थ है, सबसे प्रणाली, कि यह पार्टी विशेष सुविधाओं का उपयोग करने में सक्षम नहीं होगा पर), $! कुछ भी नहीं करने के लिए विस्तारित (क्योंकि उस खोल नहीं है किसी भी पृष्ठभूमि प्रक्रिया शुरू की), और पहली पंक्ति इंटरैक्टिव/bin/bash खोल का आह्वान करती है। फिर आप उस इंटरैक्टिव शैल से बाहर निकलें, और आपकी स्क्रिप्ट echo Hello world! लाइन निष्पादित करती है और समाप्त हो जाती है, जिससे आप अपने मूल खोल में वापस आ जाते हैं।

उदाहरण के लिए, यदि आप echo Hello world!echo $BASH_VERSION को बदलने के लिए, आप पाएंगे कि यह कुछ भी प्रिंट नहीं करता है - और अगर आप लागू इंटरैक्टिव बैश शेल से history लिखते हैं, तो कुछ भी नहीं दिखाया जाएगा।

संबंधित मुद्दे