एक स्क्रिप्ट से पूर्ण पथ का पता लगाएं


10

एक पटकथा में मैं इसके $0लिए संभावित सापेक्ष पथ में मिलता हूं । इसे पूर्ण में परिवर्तित करने के लिए मुझे यह समाधान मिला है जो मुझे समझ में नहीं आता है:

abspath=$(cd ${0%/*} && echo $PWD/${0##*/})

मेरी समस्या के अंदर ${0%/*}और जादू है ${0##*/}। ऐसा लगता है कि पूर्व में dirname अर्क है और बाद वाला फ़ाइल नाम निकालता है, मुझे अभी कैसे नहीं मिला है।


2
यह पैरामीटर विस्तार का उपयोग करता है, लेकिन यह मेरे लिए काम नहीं करता था। यदि आपकी स्क्रिप्ट केवल लिनक्स पर उपयोग होने वाली है, तो आप readlink -f $0विहित पथ प्राप्त करने के लिए उपयोग कर सकते हैं ।
Shawn J. Goff

1
@ शॉन: 1 महान टिप्पणी वोट क्योंकि आपने सही सोच पेश की: "यह पैरामीटर विस्तार का उपयोग करता है, लेकिन यह मेरे लिए काम नहीं करता था"। dirnameUtil यहाँ उपयोगी है।
D4RIO

mywiki.wooledge.org/BashFAQ/028 और cyberciti.biz/faq/... का कहना है BASH_SOURCEकी तुलना में बेहतर है $0, के रूप में $0उपयोगकर्ता के आदेश में टाइप है, जो वर्तमान में क्रियान्वित स्क्रिप्ट नहीं हो सकता है देता है।
जोएल पुर्रा

जवाबों:


8

परिभाषाएं:

${string%substring}$substringके अंत से सबसे छोटा मैच हटाता है $string

${string##substring}$substringकी शुरुआत से सबसे लंबे मैच को हटा देता है $string

आपका उदाहरण:

abspath=$(cd ${0%/*} && echo $PWD/${0##*/})

${0%/*} अंतिम स्लैश के बाद सब कुछ हटा देता है, आपको स्क्रिप्ट का निर्देशिका नाम (जो एक सापेक्ष पथ हो सकता है) देता है।

${0##*/} अंतिम स्लैश तक सब कुछ हटा देता है, जिससे आपको स्क्रिप्ट का नाम मिलता है।

तो, यह कमांड स्क्रिप्ट की डायरेक्टरी में बदल जाती है और वर्तमान वर्किंग डायरेक्टरी (द्वारा दी गई $PWD) और स्क्रिप्ट का नाम आपको पूर्ण पथ प्रदान करती है।

यह देखने के लिए कि क्या चल रहा है:

echo ${0%/*}
echo ${0##*/}

शेल विशेष वर्णों के साथ (लगभग सभी) फ़ाइल नामों के साथ सामना करने के लिए सभी चर विस्तार के आसपास दोहरे उद्धरण जोड़ें।
गाइल्स का SO- बुराई होना बंद करो '

10

शॉन का सबसे सरल उपाय था readlink -f $0:। यदि आप अजीब फ़ाइल नामों को संभालना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:

absolute_path_x="$(readlink -fn -- "$0"; echo x)"
absolute_path="${absolute_path_x%x}"

प्रलेखन


1
अंतिम न्यूलाइन्स को सही ढंग से देखने के लिए अच्छा है। दुर्भाग्य readlink -fnसे लिनक्स, NetBSD और OpenBSD के लिए विशिष्ट है।
गिल्स एसओ- बुराई को रोकना '

4

यहाँ इस काम को करने के लिए एक सुरक्षित और अधिक पठनीय तरीका है:

abspath=$(unset CDPATH && cd "$(dirname "$0")" && echo $PWD/$(basename "$0"))

टिप्पणियाँ:

  • यदि $0कोई पूर्ववर्ती पथ के साथ एक नंगे फ़ाइल नाम है, तो मूल स्क्रिप्ट विफल हो जाएगी, लेकिन यहां दिया गया एक काम करेगा। (समस्या नहीं है $0लेकिन अन्य अनुप्रयोगों में हो सकती है।)
  • यदि फ़ाइल का पथ वास्तव में मौजूद नहीं है, तो या तो दृष्टिकोण विफल हो जाएगा। (नहीं के साथ एक समस्या है $0, लेकिन अन्य अनुप्रयोगों में हो सकता है।)
  • unsetआवश्यक अपने उपयोगकर्ता हो सकता है अगर है CDPATHनिर्धारित किया है।
  • इसके विपरीत readlink -fया realpath, यह यूनिक्स के गैर-लिनक्स संस्करणों (जैसे, मैक ओएस एक्स) पर काम करेगा।

2

यदि आप शेल पैरामीटर विस्तार सीखना चाहते हैं, तो आप इसे यहाँ से पढ़ सकते हैं , लेकिन विस्तार हमेशा एक अच्छा विकल्प नहीं है। इस मामले में, लगभग हर यूनिक्स जैसे सिस्टम में 2 अच्छे बर्तन हैं:

basename
dirname

पहला फ़ाइल नाम निकालेगा, जबकि दूसरा रास्ता निकालेगा, इसलिए, यदि आपके पास $ 0 है, तो कहें:

dirname $0

और राह मिल जाएगी।

चियर्स


dirname रिश्तेदार रास्तों पर लौट सकता है
Opticyclic

0

पेश है पीडब्लू, बैश बिलिन। जीएनयू कोरुटिल्स पैकेज में भी पाया गया।

$ sh ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
$0: ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
cheeky binary from /home/jaroslav/tmp (/home/jaroslav/tmp)

$ cat /home/jaroslav/tmp/somewhere.sh

abs=$( cd `dirname "$0"` ; pwd -P)
absBin=$( cd `dirname "$0"` ; /bin/pwd -P)
echo \$0: $0
echo cheeky binary from $abs \($absBin\)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.