सिम्पीनल के माध्यम से निष्पादित होने पर वर्तमान स्क्रिप्ट का पथ प्राप्त करें


58

मेरे पास कुछ बैश स्क्रिप्ट और सहायक फ़ाइलों के साथ एक युगल निर्देशिकाओं की एक उपयोगिता है जो प्रत्येक मशीन के लिए एक अलग निर्देशिका में संभवतः कई मशीनों पर तैनात की जाएगी। स्क्रिप्ट को स्वयं के सापेक्ष पथों को संदर्भित करने में सक्षम होने की आवश्यकता है इसलिए मुझे उस फ़ाइल को पथ प्राप्त करने में सक्षम होने की आवश्यकता है जिसे वर्तमान में निष्पादित किया जा रहा है।

मुझे उस dirname $0मुहावरे के बारे में पता है जो पूरी तरह से काम करता है जब मेरी स्क्रिप्ट को सीधे कहा जाता है। दुर्भाग्य से एक पूरी तरह से अलग निर्देशिका से इन लिपियों के लिए सहानुभूति बनाने में सक्षम होने की इच्छा है और अभी भी सापेक्ष पथ तर्क काम है।

समग्र सुस्पष्ट संरचना का एक उदाहरण इस प्रकार है:

/
 |-usr/local/lib
 |  |-foo
 |  |  |-bin
 |  |  |  |-script.sh
 |  |  |-res
 |  |  |  |-resource_file.txt
 |-home/mike/bin
 |  |-link_to_script (symlink to /usr/local/lib/foo/bin/script.sh)

मैं इसका संदर्भ कैसे दे सकता हूं /usr/local/lib/foo/res/resource_file.txt, script.shक्या यह इसके द्वारा लागू किया गया है /usr/local/lib/foo/bin/script.shया नहीं ~mike/bin/link_to_script?

जवाबों:


79

इसे एक सामान्य उद्देश्य समाधान के रूप में आज़माएं:

DIR="$(cd "$(dirname "$0")" && pwd)"

निम्नलिखित सिम्बलिंक के विशिष्ट मामले में, आप यह भी कर सकते हैं:

DIR="$(dirname "$(readlink -f "$0")")"

पूरी तरह से काम करता है और जिस तरह से मैं कोशिश कर रहा था की तुलना में आसान है। धन्यवाद!
माइक डेक

@MikeDeck आनंद लें। ध्यान दें कि मैंने पहली पोस्टिंग के बाद से कुछ उद्धृत मुद्दे तय किए हैं ... आप इस घटना में नवीनतम संपादन से एक विकल्प का उपयोग कर सकते हैं कि आपके पास कुछ समय में रिक्त स्थान या अन्य निराला वर्ण हैं। यहां तक ​​कि अगर यह इस परियोजना के लिए कोई फर्क नहीं पड़ता है, तो आप सड़क से नीचे अपनी स्क्रिप्ट से कोड की प्रतिलिपि बना सकते हैं और तब सबसे अच्छा विकल्प मायने रखता है!
कालेब

1
मुझे स्पष्ट करना चाहिए, दूसरा पूरी तरह से काम करता है। आपके द्वारा दिया गया पहला समाधान मेरे सिस्टम पर सहानुभूति के लिए काम नहीं करता है।
माइक डेक

4
@ माइकडेक: पहला समाधान पथ के हिस्से के रूप में सहानुभूति रखने वाले विभिन्न निर्देशिकाओं के विशिष्ट मामले के लिए काम करता है, लेकिन अंतिम बाइनरी एक सिमलिंक होने पर मदद नहीं करेगा। यही कारण है कि दूसरे का ख्याल रखना है।
कालेब

1
काम नहीं करता है अगर स्क्रिप्ट फ़ाइल sourced है (उदाहरण के लिए $ source ./sript.sh) यह दोनों मामलों के लिए काम करता है:DIR="$(cd "$(dirname "$BASH_SOURCE")" && pwd)"
FractalSpace

7

एक पंक्ति:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))

2
एक पंक्ति के उत्तर आमतौर पर सबसे अधिक उपयोगी नहीं होते हैं। स्पष्टीकरण, लिंक या प्रलेखन को शामिल करने के लिए कृपया अपने उत्तर का विस्तार करने पर विचार करें जो आपके सुझाए गए समाधान का समर्थन करते हैं।
हेलोसिहॉस्ट

1
वास्तव में, आपको ऐसा करने की आवश्यकता नहीं है, मूल उत्तर का रीडलिंक संस्करण ठीक काम करता है अगर कोई
सिम्कलिन

3

readlink -f मेरे लिए काम नहीं करता है, मैं यह गलती कर रहा हूँ:

readlink: illegal option -- f
usage: readlink [-n] [file ...]

लेकिन यह ठीक काम करता है:

DIR="$(dirname "$(readlink "$0")")"
echo $DIR


हां, मैं MacOs @isaac पर हूं, लेकिन मेरे पास कोई सवाल नहीं है। मैंने अपनी तरफ से काम करने वाली कमांड पोस्ट की।
केविन कैंपियन

0

उपरोक्त लिपि का एक छोटा जोड़। Pwd के लिए -P विकल्प सिमिलिंक का अनुसरण करता है

DIR="$(cd "$(dirname "$0")" && pwd -P)"

7
यह केवल तभी काम करता है जब सिम्लिंक निर्देशिका संरचना का हिस्सा है। यह तब काम नहीं करता जब फ़ाइल खुद से जुड़ी होती है।
ओलिवर गोंडस्टा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.