$ PATH में मिली स्क्रिप्ट की उसी निर्देशिका के तहत एक फ़ाइल का संदर्भ लें


33

मेरे पास एक bash स्क्रिप्ट फ़ाइल है, जिसे $ PATH में जोड़े गए कुछ डायरेक्टरी के तहत रखा गया है ताकि मैं किसी भी डायरेक्टरी से स्क्रिप्ट को कॉल कर सकूं।

स्क्रिप्ट के समान निर्देशिका के तहत एक और पाठ फ़ाइल है। मुझे आश्चर्य है कि स्क्रिप्ट में पाठ फ़ाइल को कैसे देखें?

उदाहरण के लिए, यदि स्क्रिप्ट सिर्फ टेक्स्ट फ़ाइल की सामग्री को आउटपुट करने के लिए है, तो cat textfileकाम नहीं करेगा, क्योंकि स्क्रिप्ट को किसी अलग निर्देशिका से कॉल करने के बाद, टेक्स्ट फ़ाइल नहीं मिलती है।



यह प्रश्न उत्तर देता है कि कैसे एक बाश स्क्रिप्ट फ़ाइलों को मज़बूती से प्राप्त करने के लिए, मैंने उसे अपने पथ पर जोड़ा: stackoverflow.com/q/4774054/1695680
ThorSummoner

जवाबों:


24

ये उसी तरह से काम करना चाहिए, जब तक कि कोई सहानुभूति नहीं है (पथ विस्तार या स्क्रिप्ट में ही):

  • MYDIR="$(dirname "$(realpath "$0")")"

  • MYDIR="$(dirname "$(which "$0")")"

  • उपरोक्त में से किसी एक का दो चरण संस्करण:

    MYSELF="$(realpath "$0")"

    MYDIR="${MYSELF%/*}"

यदि आपकी स्क्रिप्ट के रास्ते में कोई सिमलिंक है, तो whichउस लिंक के रिज़ॉल्यूशन सहित उत्तर नहीं देगा। यदि realpathआपके सिस्टम पर डिफ़ॉल्ट रूप से इंस्टॉल नहीं किया गया है, तो आप इसे यहां पा सकते हैं

[संपादित करें]: जैसा कि ऐसा लगता है कि कालेब द्वारा सुझाए गएrealpath पर कोई फायदा नहीं है , यह शायद बाद का उपयोग करने के लिए बेहतर है। मेरे समय परीक्षण से संकेत मिलता है कि यह वास्तव में तेज है।readlink -f


कोई बात नहीं। वैसे realpathआपके सिस्टम पर कहां से आता है। (दूसरों के लिए जो आपके पास नहीं है, वे उपयोग कर सकते हैंreadlink -f
कालेब

@ कालेब वास्तव में मुझे लगा कि यह मानक GNU उपयोगिताओं (कोरुटिल्स) के सेट से संबंधित है, लेकिन मैं देख सकता हूं कि यह एक अलग पैकेज है
rozcietrzewiacz

@rozcietrzewiacz , GNU कोरुटिल्स में realpathपहले readlink -f(और यहां तक ​​कि readlink, IIRC) से पीछे था (वहाँ कई समान उपकरण थे। readlink -fआखिरकार डी फैक्टो मानक बन गया); realpathकेवल उन लिपियों के साथ संगतता के लिए रखा जाता है जो अभी भी इसका उपयोग करते हैं।
गिलेस एसओ- बुराई को रोकना '

अब मौजूद नहीं है, जहां $(dirname "$(which "$0")")पर फायदा क्या है? क्या यह समान नहीं है? $(dirname $0)which
उल्फत

readlink -fमैक ओएस एक्स 10.11.6 पर realpathकाम नहीं करता है , लेकिन बॉक्स से बाहर काम करता है।
गौरव

9

मेरे प्रणाली की जरूरत नहीं है realpathके रूप में rozcietrzewiacz ने सुझाव दिया

आप readlinkकमांड का उपयोग करके इसे पूरा कर सकते हैं । इस ओवर पार्सिंग whichया अन्य समाधानों का उपयोग करने का लाभ यह है कि भले ही रास्ते का एक हिस्सा या फ़ाइल नाम निष्पादित सिम्लिंक था, आप उस निर्देशिका को खोजने में सक्षम होंगे जहां वास्तविक फ़ाइल थी।

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

आपकी पाठ फ़ाइल को इस तरह एक चर में पढ़ा जा सकता है:

TEXTFILE="$(<$MYDIR/textfile)"

@rozcietrzewiacz: मैं वास्तव में सिर्फ आपके whichसुझाव का संदर्भ नहीं दे रहा था । इस के लिए सामान्य समाधान या तो बस शामिल है dirnameया का एक संयोजन cdऔर pwdएक subshell में। रीडलिंक का यहाँ लाभ है। realpathलगता है बहुत ज्यादा readlink -fवैसे भी सिर्फ एक रैपर हो सकता है।
कालेब

मुझे नहीं पता कि कैसे realpathअलग है readlink -f। मैं केवल यह देख सकता हूं कि यह मुझे वही परिणाम देता है (जैसा कि विरोध किया गया है which)।
rozcietrzewiacz

ध्यान रखें कि readlink -f(GNU कोरुटिल्स से) को अस्तित्व के अंतिम तत्व की आवश्यकता नहीं है, readlink -eकरता है, लेकिन इसका समर्थन नहीं करता है busybox readlink, जो -eउनके -fविकल्प के व्यवहार की नकल करता है ।
ड्रैगन 788

8

$0स्क्रिप्ट में स्क्रिप्ट के लिए पूर्ण पथ dirnameहोगा , और एक पूर्ण पथ लेगा और आपको बस निर्देशिका देगा, इसलिए आप इसे टेक्स्टफाइल को कैट करने के लिए कर सकते हैं:

$ cat "$(dirname -- "$0")/textfile"

जबकि यह बिना काम के लगता है realpath $0, आप यह कहने में गलत हैं कि " $0स्क्रिप्ट में स्क्रिप्ट का पूरा रास्ता होगा"।
रोज़ज़ेट्रिएवेज़ ज़ूल

@roz किस तरीके से?
माइकल Mrozek

1
$0यह कमांड है जैसा कि इसे चलाया गया था, जो उदाहरण के लिए हो सकता है ../script.sh
रोज़ज़ेट्रिविएज़ ज़ूल

इसलिए, वास्तव में लिपि $(dirname "$0")के सापेक्ष पथ को लौटाता है , आह्वान किए गए आदेश के भाग के रूप में - निरपेक्ष पथ नहीं। इससे स्क्रिप्ट में समस्याएं हो सकती हैं जो दौड़ते समय निर्देशिकाओं को बदल देती हैं।
rozcietrzewiacz

@roz आह, दिलचस्प। इसलिए मुझे लगता है कि यह यहाँ एक समस्या का कारण नहीं होगा क्योंकि वह नाम से पथ पर कुछ कह रहा है, लेकिन यह अन्य चीजों को तोड़ देगा। धन्यवाद
माइकल Mrozek

4

आप इसे अपनी लिपि में सबसे ऊपर रख सकते हैं:

cd "${BASH_SOURCE%/*}" || exit

BASH_SOURCE आंतरिक बैश वैरिएबल वास्तव में पथनामों की एक सरणी है। यदि आप इसे एक साधारण स्ट्रिंग के रूप में विस्तारित करते हैं, उदाहरण के लिए "$ BASH_SOURCE", तो आपको पहला तत्व मिलेगा, जो वर्तमान में निष्पादित फ़ंक्शन या स्क्रिप्ट का पथनाम है।

स्रोत: http://mywiki.wooledge.org/BashFAQ/028


2

मैं इन कोशिश कर रहा था और realpath मेरे लिए काम नहीं किया। समाधान मैं साथ चला गया है:

SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

जिसने अब तक अच्छा काम किया है। मैं जानना चाहूंगा कि क्या दृष्टिकोण के साथ कोई संभावित मुद्दे हैं।


1
अच्छा है, लेकिन सहानुभूति का पालन नहीं करता है। इसे आज़माएं:SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
OronNavon

1

मैं उपयोग करता हूं:

#! /bin/sh -
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P) || exit
dosomethingwith "${dir%/}/some-file"

जो POSIX है और जब तक $0newline वर्णों में समाप्त नहीं होता है, तब तक काम नहीं करना चाहिए , -और $CDPATHसेट नहीं किया जाता है (और संभवतः कुछ अन्य कोने के मामले यदि स्क्रिप्ट को देखा नहीं गया था $PATH)।


0

मैं हमेशा whichPATH से एक निष्पादन योग्य का पूरा रास्ता खोजने के लिए उपयोग करता हूं । उदाहरण के लिए:

which python

यदि आप इसे dirnameकमांड के साथ जोड़ते हैं तो आपको मिलता है:

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