$ 0 और BASH_SOURCE के बीच चयन करना


118

कैसे "$0"और के बीच चयन करता है"${BASH_SOURCE[0]}"

जीएनयू के इस विवरण से मुझे बहुत मदद नहीं मिली।

    BASH_SOURCE

 An array variable whose members are the source filenames where the
 corresponding shell function names in the FUNCNAME array variable are
 defined. The shell function ${FUNCNAME[$i]} is defined in the file
 ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}

BASH_SOURCEबैश-3.0-अल्फा में जोड़ा गया था। आपके पास यह नहीं हो सकता है, आपके परीक्षण शासन पर निर्भर करता है। मुझे यह शुरुआती सोलारिस और ओएस एक्स दोनों पर गायब पाया गया। वापसी भी देखें : केवल एक समारोह या U.S और L.SE पर स्रोत से वापसी कर सकते हैं
jww

जवाबों:


174

नोट: POSIX- अनुरूप समाधान के लिए, यह उत्तर देखें ।

${BASH_SOURCE[0]}(या, और अधिक सरलता से, $BASH_SOURCE[१] ) में सम्‍मिलित सभी परिदृश्‍यों में लिपि का (संभावित सापेक्ष) पथ सम्‍मिलित है, विशेष रूप से लिपि के खट्टे होने पर भी , जो कि सही नहीं है $0

इसके अलावा, जैसा कि चार्ल्स डफी बताते हैं, कॉलर द्वारा $0एक मनमाना मूल्य निर्धारित किया जा सकता है ।
फ्लिप पक्ष पर, खाली $BASH_SOURCE हो सकता है, अगर कोई नामित फ़ाइल शामिल नहीं है; उदाहरण के लिए:
echo 'echo "[$BASH_SOURCE]"' | bash

निम्न उदाहरण यह दिखाता है:

स्क्रिप्ट foo:

#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"

$ bash ./foo
[./foo] vs. [./foo]

$ ./foo
[./foo] vs. [./foo]

$ . ./foo
[bash] vs. [./foo]

$0POSIX शेल विनिर्देशन का हिस्सा है, जबकि BASH_SOURCE, जैसा कि नाम से पता चलता है, यह बैश-विशिष्ट है।


[1] वैकल्पिक पढ़ने: ${BASH_SOURCE[0]}बनाम$BASH_SOURCE :

बैश आपको स्केलर नोटेशन का उपयोग करके 0एक सरणी चर के तत्व को संदर्भित करने की अनुमति देता है: लिखने के बजाय , आप लिख सकते हैं ; दूसरे शब्दों में: यदि आप चर को संदर्भित करते हैं जैसे कि यह एक अदिश राशि है , तो आपको तत्व इंडेक्स पर मिलता है । ${arr[0]}$arr0

इस सुविधा का उपयोग इस तथ्य को अस्पष्ट करता है कि $arrएक सरणी है, यही वजह है कि लोकप्रिय शेल-कोड लिंटर शेलचेक.नेट निम्नलिखित चेतावनी जारी करता है (इस लेखन के रूप में):

SC2128: किसी अनुक्रमणिका के बिना किसी सरणी का विस्तार केवल पहला तत्व देता है।

एक साइड नोट पर: जबकि यह चेतावनी सहायक है, यह अधिक सटीक हो सकता है, क्योंकि आपको आवश्यक रूप से पहला तत्व नहीं मिलेगा : यह विशेष रूप से सूचकांक में तत्व 0है जो वापस आ गया है, इसलिए यदि पहले तत्व में उच्च सूचकांक है - जो बैश में संभव है - आप खाली स्ट्रिंग प्राप्त करेंगे; कोशिश करो 'a[1]='hi'; echo "$a"'
(इसके विपरीत, zshकभी पाखण्डी, वास्तव में करता है पहला तत्व लौटने अपने सूचकांक पर ध्यान दिए बिना,)।

आप इसकी अस्पष्टता के कारण इस सुविधा को बचाना चुन सकते हैं, लेकिन यह पूर्वानुमान और व्यावहारिक रूप से काम करता है, आप शायद ही कभी, यदि कभी भी, सूचकांकों तक पहुँचने की आवश्यकता हो, 0 सरणी चर के अलावा अन्य की आवश्यकता होती है ${BASH_SOURCE[@]}


इसलिए $ BASH_SOURCE अधिक सामान्य है और अधिक परिस्थितियों में काम करता है?
अलेक्जेंडर मिल्स

2
यदि आप बैश का उपयोग कर रहे हैं, तो @AlexanderMills $BASH_SOURCEबेहतर विकल्प है।
mklement0

18

ये स्क्रिप्ट चित्रण में मदद कर सकती हैं। बाहरी स्क्रिप्ट मध्य स्क्रिप्ट को कॉल करती है, जो आंतरिक स्क्रिप्ट को कॉल करती है:

$ cat outer.sh
#!/usr/bin/env bash
./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './inner.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = ''
$BASH_SOURCE[2] = ''

हालाँकि, यदि हम स्क्रिप्ट कॉल को sourceस्टेटमेंट्स में बदलते हैं :

$ cat outer.sh
#!/usr/bin/env bash
source ./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
source ./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './outer.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = './middle.sh'
$BASH_SOURCE[2] = './outer.sh'

1

पोर्टेबिलिटी के लिए, ${BASH_SOURCE[0]}इसे परिभाषित करते समय उपयोग करें , और $0अन्यथा। देता है कि

${BASH_SOURCE[0]:-$0}

विशेष रूप से, कहना है कि zsh में, $ 0 में सही फ़ाइलपथ है, भले ही स्क्रिप्ट sourced हो।

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