कॉल फंक्शन नीचे घोषित


15

क्या किसी फ़ंक्शन को कॉल करना संभव है, जो नीचे बैश में घोषित किया गया है?

उदाहरण

if [ "$input" = "yes" ]; then
    YES_FUNCTION
elif [ "$input" = "no" ]; then
    NO_FUNCTION
else
    exit 0;
fi

YES_FUNCTION()
{
  .....
  .....
}

NO_FUNCTION()
{
  .....
  .....
}

जवाबों:


37

जैसे दूसरों ने कहा है, आप ऐसा नहीं कर सकते।

लेकिन अगर आप कोड को एक फ़ाइल में व्यवस्थित करना चाहते हैं ताकि मुख्य कार्यक्रम फ़ाइल के शीर्ष पर हो, और अन्य फ़ंक्शन नीचे परिभाषित किए गए हैं, तो आप इसे एक अलग mainफ़ंक्शन करके कर सकते हैं ।

उदाहरण के लिए

#!/bin/sh

main() {
    if [ "$1" = yes ]; then
        do_task_this
    else
        do_task_that
    fi
}

do_task_this() {
    ...
} 
do_task_that() {
    ...
} 

main "$@"; exit

जब हम mainफ़ाइल के अंत में कॉल करते हैं, तो सभी फ़ंक्शन पहले से ही परिभाषित होते हैं। फ़ंक्शन में दिखाई देने वाली स्क्रिप्ट की कमांड लाइन तर्क बनाने के "$@"लिए स्पष्ट रूप से पारित करना mainआवश्यक है।

exitकॉल टू मेन के रूप में एक ही लाइन पर स्पष्ट अनिवार्य नहीं है, लेकिन एक रनिंग स्क्रिप्ट को स्क्रिप्ट फ़ाइल में संशोधित होने से बचाने के लिए उपयोग किया जा सकता है। इसके बिना, शेल mainरिटर्न के बाद स्क्रिप्ट फ़ाइल से कमांड पढ़ना जारी रखने का प्रयास करेगा । ( इसे निष्पादित करने से पहले संपूर्ण शेल स्क्रिप्ट कैसे पढ़ें? देखें )


@ikkachu लगता है कि यह काम करना चाहिए .. मुझे जांचने दो।
msp9011

8
बैश स्क्रिप्ट के साथ, मैं अक्सर [[ ${BASH_SOURCE[0]} = "$0" ]] && Main "$@"मुख्य फ़ंक्शन को कॉल करने के लिए उपयोग करता हूं ताकि मैं इसे किसी अन्य स्क्रिप्ट Mainमें निष्पादित किए बिना ही स्रोत कर सकूं। फिर मैं या तो कार्यों का पुन: उपयोग कर सकता हूं या उन्हें जांचने के लिए परीक्षण लिख सकता हूं।
ब्लैकजैक

11
होने main "$@"; exit( exitउसी लाइन पर main) के साथ भी उपयोगी है क्योंकि फाइल की व्याख्या की जा रही है, जबकि इसे संरक्षित किया जा रहा है।
स्टीफन चेज़लस

2
@JoL, जो पढ़ा गया है वह फिर से नहीं पढ़ा जाता है, और शेल को इसे चलाने के लिए शुरू करने से पहले एक लूप के पूरे पाठ को पढ़ना और पार्स करना होगा, लेकिन फिर लूप के वापस आने के बाद यह बाकी फाइल से रीडिंग लेगा वर्तमान स्थिति (और अगर फ़ाइल को संशोधित किया गया है तो यह चीजों को खराब कर देगा)। यदि सब कुछ फ़ंक्शन में है, तो शेल को कुछ भी करने के लिए शुरू करने से पहले सब कुछ पढ़ने की जरूरत है (उन कार्यों को परिभाषित करने के अलावा), अगर हम exitउसी लाइन पर डालते हैं जैसा कि mainहम सुनिश्चित करते हैं कि शेल mainरिटर्न के बाद फ़ाइल से फिर से कुछ भी नहीं पढ़ेगा ।
स्टीफन चेज़लस

1
@MontyHarder, यदि आप उपयोग करते हैं main; exit, तो इससे कोई फर्क नहीं पड़ता है , main; exit $?या main <EOF>, सभी मामलों mainमें स्क्रिप्ट के निकास कोड के रूप में निकास कोड का उपयोग किया जाता है। exitकिसी स्क्रिप्ट के चलते समय संपादित करता है, तो सिर्फ बातें में गड़बड़ हो रही रोकने के लिए किया जाएगा।
ilkachachu

14

नहीं, फ़ंक्शन को कॉल करने के समय गोले के वातावरण में मौजूद होना चाहिए।

Google की "शेल स्टाइल गाइड" में इसके लिए एक निश्चितता है:

एक फ़ंक्शन जिसे mainस्क्रिप्ट कहा जाता है, उसके लिए आवश्यक है कि कम से कम एक अन्य फ़ंक्शन शामिल हो।

स्क्रिप्ट के बहुत अंत में, सभी फ़ंक्शन के बाद, केवल एक फ़ंक्शन में कथन नहीं, आपके पास होगा

main "$@"

यह mainफ़ंक्शन को स्क्रिप्ट के दिए गए सभी मापदंडों के साथ कॉल करेगा । mainसमारोह स्क्रिप्ट के शीर्ष पर स्थित किया जा सकता है (शैली गाइड तल पर यह डाल करने के लिए कहते हैं, लेकिन फिर, यह बहुत सी बातें कहते हैं)।

जब शेल mainकॉल पर जाता है , तो स्क्रिप्ट में सभी फ़ंक्शन पार्स किए गए हैं और इसलिए इसे mainफ़ंक्शन के भीतर से कॉल किया जा सकता है।


9

नहीं, फ़ंक्शंस का उपयोग करने से पहले उन्हें घोषित किया जाना चाहिए। शैल स्क्रिप्ट लाइन द्वारा लाइन पढ़ी जाती हैं और लाइन द्वारा लाइन पर कार्रवाई की जाती हैं; इसलिए एक फ़ंक्शन मौजूद नहीं है जब तक कि इसकी घोषणा को निष्पादित नहीं किया गया है।


तुम सही हो। समस्या यह है कि मेरे पास एक स्क्रिप्ट में 30+ फ़ंक्शन हैं। जब हम कोड पढ़ते हैं तो यह काफी मुश्किल होता है। इसमें Cआराम है।
msp9011

3
आप अपनी फ़ंक्शन घोषणाओं को किसी अन्य फ़ाइल में डाल सकते हैं और इसे स्रोत कर सकते हैं ( . yourfile)।
स्टीफन किट

हां, मैंने कोशिश की है कि, लेकिन आवश्यकता एक स्क्रिप्ट की है।
msp9011

@ शिवप्रकाश वास्तव में क्या समस्या है? बस सभी फ़ंक्शन को परिभाषित करें, शायद किसी फ़ंक्शन में मुख्य कोड भी डाल रहे हैं और फिर अंतिम पंक्ति दिखाती है कि किस फ़ंक्शन को कहा जाता है और स्क्रिप्ट का मुख्य भाग होता है।
ब्लैकजैक

@ शिवप्राथ सी में, आपके पास ifएक फ़ंक्शन के बाहर नंगे बयान नहीं हैं । जब आप कॉल करते हैं तो फ़ंक्शन को -containing फ़ंक्शन की घोषणा करते समय परिभाषित नहीं किया जाता है । if
शेपनर

4

शेल में declaringफ़ंक्शन की कोई अवधारणा नहीं है। इसलिए आपके पास आगे की घोषणा नहीं हो सकती है।

एक परिणाम के रूप में, आपको इसे लागू करने से पहले शेल द्वारा फ़ंक्शन कार्यान्वयन को पढ़ने की आवश्यकता है।


4
तकनीकी तौर पर, कुछ गोले (ksh, zsh) में एक फ़ंक्शन ऑटोलॉडिंग विशेषता होती है, जिसे घोषणा के कुछ रूप के रूप में देखा जा सकता है (जहां autoload fफ़ंक्शन घोषित करता है, लेकिन इसका शरीर केवल पहले आह्वान पर लोड होता है)। bashहालांकि यह ओपी पर लागू नहीं होता है ।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.