एक बश फ़ंक्शन को कैसे परिभाषित किया जाए जो विभिन्न लिपियों द्वारा उपयोग किया जा सकता है


13

मैंने bashअपनी ~/.bashrcफ़ाइल में फ़ंक्शन को परिभाषित किया है । यह मुझे शेल टर्मिनलों में इसका उपयोग करने की अनुमति देता है। हालाँकि, यह तब नहीं लगता जब मैं इसे किसी स्क्रिप्ट के भीतर से बुलाता हूं।

मैं bashस्क्रिप्ट द्वारा उपयोग किए जाने वाले फ़ंक्शन को कैसे परिभाषित कर सकता हूं ?


लेकिन मेरा .bash_profile मूल रूप से .basrc फ़ाइल को पढ़ता है, इसलिए मुझे परिणाम की अपेक्षा होगी कि मैं लॉगिन या गैर-लॉगिन शेल का उपयोग किए बिना परिणाम समान हो।
ओंटारियोनियो

क्या आप /bin/shशबंग लाइन में उपयोग कर रहे हैं ?
केविन

जवाबों:


9

~/.bash_profileऔर ~/.bashrcस्क्रिप्ट द्वारा नहीं पढ़े जाते हैं, और फ़ंक्शन डिफ़ॉल्ट रूप से निर्यात नहीं किए जाते हैं। ऐसा करने के लिए, आप इसका उपयोग कर सकते हैं export -f:

$ cat > script << 'EOF'
#!/bin/bash
foo
EOF
$ chmod a+x script
$ ./script
./script: line 2: foo: command not found
$ foo() { echo "works" ; } 
$ export -f foo
$ ./script
works

export -f foo~/.bash_profileलॉगिन के बाद इस फ़ंक्शन को स्क्रिप्ट में उपलब्ध कराने के लिए भी बुलाया जा सकता है । चेतावनी दी है कि export -fपोर्टेबल नहीं है।

एक बेहतर समाधान फ़ाइल का उपयोग करने वाले फ़ंक्शन को स्रोत करने के लिए होगा . file। यह बहुत अधिक पोर्टेबल है, और आपके पर्यावरण पर एक विशेष तरीके से स्थापित होने पर निर्भर नहीं करता है।


क्यों नहीं की तरह एक समारोह की घोषणा function myFunction { ... }में ~/.bash_profileऔर आप अच्छा जाना चाहते हैं?
उभयलिंगी

अगर मुझे आपका उत्तर ठीक से समझ में आ रहा है (फ़ंक्शन के साथ किसी फ़ाइल को सोर्स करने के बारे में), इसका मतलब यह होगा कि मुझे हर स्क्रिप्ट में स्पष्ट रूप से फ़ाइल को स्रोत करना होगा, जो कि बहुत कष्टप्रद है। यह केवल प्रत्येक स्क्रिप्ट में फ़ंक्शन को कॉपी-पेस्ट करने की तुलना में बहुत कम जटिल नहीं है। मैं कुछ पंक्तियों को सहेजता हूँ, ज़रूर, लेकिन यह सब है। हालांकि, exportसमाधान ठीक से काम करने लगता है। धन्यवाद।
ओंटुरेनियो

@foampile, यह ठीक वही है जो मैंने किया था और स्क्रिप्ट से फ़ंक्शन को कॉल करते समय काम नहीं करता है।
ओंटुरेनियो

1
@Onturenio: दूसरी विधि @ क्रिस-डाउन प्रस्तावित वास्तव में बेहतर है: 1) जब कोई व्यक्ति स्क्रिप्ट पढ़ता है, तो वे जानते हैं कि इसे fooकुछ file2 से कुछ फ़ंक्शन की आवश्यकता है ) आप बेहतर सामग्री को नियंत्रित कर सकते fileहैं सुनिश्चित करें कि इनवोक शेल fooअपनी स्क्रिप्ट को लागू करने से पहले नहीं बदला । fileउदाहरण के लिए, यह सुनिश्चित करने के लिए कि आप सुरक्षा जाँच जोड़ सकते हैं । (आसान नहीं है, लेकिन संभव है)। (ठीक है, आप उन चेकों को परिभाषित फू फ़ंक्शन पर भी कर सकते हैं ... लेकिन आप मेरा बहाव प्राप्त करें ^ ^ मुझे लगता है कि विधि 2 क्लीनर है।) 3) fileमें केवल वही होगा जो आवश्यक है, अधिक नहीं।
ओलिवियर दुलक

8

.bashrcकेवल इंटरैक्टिव गोले द्वारा पढ़ा जाता है। (वास्तव में, यह एक अधिक महत्व है: इस संबंध में बैश विचित्र है। बैश यह नहीं पढ़ता है .bashrcकि यह एक लॉगिन शेल है, इंटरएक्टिव है या नहीं। और अपवाद के अलावा भी एक अपवाद है: यदि बैश की मूल प्रक्रिया है rshdया sshd, तो बैश पढ़ा नहीं जा सकता है .bashrc) इंटरएक्टिव है या नहीं।)

किसी ज्ञात स्थान पर किसी फ़ाइल में अपनी फ़ंक्शन परिभाषाएँ रखें, और उस फ़ाइल को स्क्रिप्ट में शामिल करने के लिए .(वर्तनी भी source) बिल्ट का उपयोग करें ।

$ cat ~/lib/bash/my_functions.bash
foo () {

$ cat ~/bin/myscript
#!/bin/bash
. ~/lib/bash/my_functions.bash
foo bar

आप चाहें तो ksh के ऑटोलैड फीचर को फॉलो कर सकते हैं। प्रत्येक फ़ंक्शन परिभाषा को फ़ंक्शन के समान नाम वाली फ़ाइल में रखें। FPATHचर में फ़ंक्शन परिभाषाओं वाली निर्देशिकाओं को सूचीबद्ध करें (निर्देशिकाओं की एक बृहदान्त्र-पृथक सूची)। यहाँ ksh का एक कच्चा सन्निकटन है autoloadजो वास्तव में ऑन-डिमांड के बजाय फ़ंक्शन को तुरंत लोड करता है:

autoload () {
  set -- "$(set +f; IFS=:;
            for d in $FPATH; do
              if [ -r "$d/$1" ]; then echo -E "$d/$1"; break; fi;
            done)"
  [[ -n $1 ]] && . "$1"
}

ऑटोलैड के लिए +1, हालांकि मैं बैश के साथ आने वाले लोगों का उपयोग करने की सलाह देता हूं। नवीनतम एक आलसी लोड का समर्थन करता है।
स्टारफिश

0

क्या आपको एक फ़ंक्शन की आवश्यकता है? यदि नहीं, तो अपने में तर्क को एक अलग, स्टैंड-अलोन बैश स्क्रिप्ट में खींचने पर विचार करें $PATH। उदाहरण के लिए, मेरे पास यह था ~/.bashrc:

# echo public IP address
alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

~/binमेरे पास है $PATH, इसलिए मैंने ~/bin/wanipनिम्नलिखित सामग्री बनाई :

#!/bin/bash

# echo public IP address
dig +short myip.opendns.com @resolver1.opendns.com

और chmod 0755 ~/bin/wanipइसे निष्पादन योग्य बनाने के लिए दौड़ा । अब मैं wanipअन्य स्क्रिप्ट से निष्पादित कर सकता हूं ।

मुझे wanipस्टैंड-अलोन बैश स्क्रिप्ट में रहना पसंद है । यह मुझे याद दिलाता है कि मैं इस तर्क को आम तौर पर उपलब्ध चाहता हूं (इसके अलावा मेरे मौजूदा इंटरैक्टिव बैश सत्र में)। स्क्रिप्ट अच्छी तरह से तर्क और उसी के लिए प्रलेखन encapsulate।

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