क्या मैं शेल स्क्रिप्ट की किसी अन्य स्क्रिप्ट से फ़ंक्शन को कॉल कर सकता हूं?


86

मेरे पास 2 शेल स्क्रिप्ट हैं।

दूसरे शेल स्क्रिप्ट में निम्नलिखित कार्य शामिल हैं

func1 
func2

फर्स्ट.श दूसरे शेल स्क्रिप्ट को कुछ मापदंडों के साथ कॉल करेगा और उस फ़ंक्शन के लिए विशिष्ट कुछ अन्य मापदंडों के साथ func1 और func2 को कॉल करेगा।

यहाँ उदाहरण है कि मैं किस बारे में बात कर रहा हूँ

second.sh

val1=`echo $1`
val2=`echo $2`

function func1 {

fun=`echo $1`
book=`echo $2`

}

function func2 {

fun2=`echo $1`
book2=`echo $2`


}

first.sh

second.sh cricket football

func1 love horror
func2 ball mystery

मैं इसे कैसे प्राप्त कर सकता हूं?


2
डुप्लिकेट - stackoverflow.com/questions/8352851/…
0xAX

3
v=$(echo $1)पूरी तरह से बेमानी है। बस लिखो fun2=$1। एकमात्र अंतर यह है कि $()(या बैकटिक्स) नई नई अनुगामी को हटा देगा।
विलियम पुरसेल

1
चूँकि कमांड लाइन के विपरीत शेल स्क्रिप्ट से किसी फ़ंक्शन को कॉल करने के बारे में कुछ खास नहीं है, इसलिए इस प्रश्न को "बैश फ़ंक्शन को कैसे कॉल करें?"
टॉम रसेल

जवाबों:


145

second.shइस तरह अपनी स्क्रिप्ट को रिफलेक्टर करें :

function func1 {
   fun=$1
   book=$2
   printf "fun=%s,book=%s\n" "${fun}" "${book}"
}

function func2 {
   fun2=$1
   book2=$2
   printf "fun2=%s,book2=%s\n" "${fun2}" "${book2}"
}

और फिर स्क्रिप्ट से इन कार्यों को first.shइस तरह से कॉल करें:

source ./second.sh
func1 love horror
func2 ball mystery

उत्पादन:

fun=love,book=horror
fun2=ball,book2=mystery

12
अनजाने दुष्प्रभावों से बचने के लिए, सावधान रहें कि sourceकमांड वास्तव में तर्क के रूप में पारित स्क्रिप्ट को चलाएगा।
डीवील्यूब

43

आप किसी अन्य शेल स्क्रिप्ट में फ़ंक्शन को सीधे कॉल नहीं कर सकते।

आप अपनी फ़ंक्शन परिभाषाओं को एक अलग फ़ाइल में ले जा सकते हैं और फिर उन्हें .इस तरह से कमांड का उपयोग करके अपनी स्क्रिप्ट में लोड कर सकते हैं :

. /path/to/functions.sh

यह इस बात की व्याख्या करेगा functions.shकि क्या यह सामग्री वास्तव में इस बिंदु पर आपकी फ़ाइल में मौजूद थी। शेल कार्यों के साझा पुस्तकालयों को लागू करने के लिए यह एक सामान्य तंत्र है।


3
क्या यह स्वीकार किए गए उत्तर के समान नहीं है, क्योंकि इसके .लिए एक उपनाम है source?
अज्शर्मा

9
ठीक है, मैंने पहले उत्तर दिया, इसलिए तकनीकी रूप से स्वीकृत उत्तर इस एक के समान है :)। इसके अलावा, जबकि कई गोले के sourceलिए एक उपनाम है ., यह हमेशा ऐसा नहीं होता है। उदाहरण के लिए, dashडेबियन पर पैकेज, जो प्रदान करता है /bin/sh, में sourceकमांड नहीं है ।
लार्क्स

sourceकमांड @ Ubuntusharma में काम नहीं किया। संदर्भ: स्रोत कमांड नहीं मिला शेल में
राजेशमग

इतना अजीब है कि यह टिप्पणी उच्चतम के रूप में उत्कीर्ण नहीं है? यह सही है #! / Bin / sh सिंटैक्स और दूसरा केवल बैश में काम करेगा।
xddq

20

समस्या

महत्वपूर्ण रूप से स्वीकृत उत्तर केवल महत्वपूर्ण स्थिति में काम करता है। दिया हुआ...

/foo/bar/first.sh:

function func1 {  
   echo "Hello $1"
}

तथा

/foo/bar/second.sh:

#!/bin/bash

source ./first.sh
func1 World

यह केवल तभी काम करता है जब इसे first.shउसी निर्देशिका के भीतर से निष्पादित किया first.shजाता है जहां स्थित है। अर्थात। यदि शेल का वर्तमान कार्य पथ है /foo, तो कमांड चलाने का प्रयास

cd /foo
./bar/second.sh

प्रिंट त्रुटि:

/foo/bar/second.sh: line 4: func1: command not found

ऐसा इसलिए है क्योंकि यह source ./first.shवर्तमान कार्य पथ के सापेक्ष है, लिपि का मार्ग नहीं। इसलिए एक समाधान सबस्क्रिप्शन और रन का उपयोग करने के लिए हो सकता है

(cd /foo/bar; ./second.sh)

अधिक सामान्य समाधान

दिया हुआ...

/foo/bar/first.sh:

function func1 {  
   echo "Hello $1"
}

तथा

/foo/bar/second.sh:

#!/bin/bash

source $(dirname "$0")/first.sh

func1 World

फिर

cd /foo
./bar/second.sh

प्रिंट

Hello World

यह काम किस प्रकार करता है

  • $0 निष्पादित स्क्रिप्ट के सापेक्ष या निरपेक्ष पथ देता है
  • dirname निर्देशिका के सापेक्ष पथ देता है, जहां $ 0 स्क्रिप्ट मौजूद है
  • $( dirname "$0" )dirname "$0"आदेश निष्पादित स्क्रिप्ट है, जो तब के लिए तर्क के रूप में प्रयोग किया जाता है की सूची के सापेक्ष पथ रिटर्न sourceआदेश
  • "second.sh" में, /first.shकेवल आयातित शेल स्क्रिप्ट का नाम जोड़ा गया है
  • source वर्तमान शेल में निर्दिष्ट फ़ाइल की सामग्री लोड करता है

0

यदि आप परिभाषित करते हैं

    #!/bin/bash
        fun1(){
          echo "Fun1 from file1 $1"
        }
fun1 Hello
. file2 
fun1 Hello
exit 0

in file1 (chmod 750 file1) और file2

   fun1(){
      echo "Fun1 from file2 $1"
    }
    fun2(){
      echo "Fun1 from file1 $1"
    }

और चलाएँ ।/ile2 आपको file1 से Fun1 मिलेगा। Hello2 Fun1 को file2 से नमस्कार! आप फ़ाइल 1 से fun1 के साथ file1 में fun1 को अधिलेखित करें ... ताकि ऐसा न हो इसलिए आपको करना चाहिए

declare -f pr_fun1=$fun1
. file2
unset -f fun1
fun1=$pr_fun1
unset -f pr_fun1
fun1 Hello

यह fun1 के लिए आपकी पिछली परिभाषा को सहेजता है और पिछले नाम को हटाने के साथ इसे पुनर्स्थापित करता है जो आयातित नहीं है। हर बार जब आप दूसरी फ़ाइल से फ़ंक्शंस आयात करते हैं तो आपको दो पहलू याद हो सकते हैं:

  1. आप मौजूदा नामों को उन्हीं नामों से अधिलेखित कर सकते हैं (यदि आप जिस चीज़ को चाहते हैं, उन्हें ऊपर बताए अनुसार संरक्षित करना चाहिए)
  2. आयात फ़ाइल की सभी सामग्री आयात करें (फ़ंक्शन और वैश्विक चर भी) सावधान रहें! यह खतरनाक प्रक्रिया है

-5
#vi function.sh

#!/bin/bash
f1() {
    echo "Hello $name"
}

f2() {
    echo "Enter your name: "
    read name
    f1
}
f2

#sh function.sh

यहां फ़ंक्शन f2कॉल करेगा फ़ंक्शनf1

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