खट्टे खोल स्क्रिप्ट के लिए पथ का निर्धारण


80

क्या एक खट्टा खोल स्क्रिप्ट के लिए खुद को रास्ता खोजने के लिए एक रास्ता है? मैं मुख्य रूप से बैश से संबंधित हूं, हालांकि मेरे पास कुछ सहकर्मी हैं जो टीसीएस का उपयोग करते हैं।

मैं अनुमान लगा रहा हूं कि मेरे पास यहां एक टन नहीं हो सकता है, क्योंकि सोर्सिंग के कारण वर्तमान शेल में निष्पादित किया जा सकता है, इसलिए $0अभी भी वर्तमान शेल का आह्वान है, खटारा स्क्रिप्ट नहीं। मेरा सबसे अच्छा विचार वर्तमान में करना है source $script $script, ताकि पहले स्थितीय पैरामीटर में आवश्यक जानकारी हो। किसी के पास एक बेहतर तरीका है?

स्पष्ट होने के लिए, मैं स्क्रिप्ट को सोर्स कर रहा हूं , इसे नहीं चला रहा हूं :

source foo.bash

संबंधित प्रश्न जिसमें 4200+ अपवोट हैं: stackoverflow.com/q/59895/52074
ट्रेवर बॉयड स्मिथ

जवाबों:


65

में tcsh, $_स्क्रिप्ट की शुरुआत में वह स्थान है, तो फ़ाइल sourced किया गया था और होगा $0यह होता है कि उसे चलाया गया था।

#!/bin/tcsh
set sourced=($_)
if ("$sourced" != "") then
    echo "sourced $sourced[2]"
endif
if ("$0" != "tcsh") then
    echo "run $0"
endif

बैश में:

#!/bin/bash
[[ $0 != $BASH_SOURCE ]] && echo "Script is being sourced" || echo "Script is being run"

मैं सिर्फ tsh में इस का उपयोग करने के लिए अवसर था, और देखा कि यह शेल्फ़ के बिना काम नहीं करता है। व्यवहार में बदलाव के लिए थोड़ा अजीब लगता है अगर आप इसे
सोर्स

यदि स्क्रिप्ट को बिना किसी सीमा के उदासीन किया जाता है तो tcsh संस्करण भी काम नहीं करता है (जैसे कि cshrc से)। मुझे उस मामले में जानकारी प्राप्त करने का कोई तरीका नहीं मिल रहा है। कोई विचार?
कास्कैबेल

सोर्सिंग यह मेरे लिए शेबंग के बिना काम करता है। > tcsh --version\n tcsh 6.14.00 (Astron) 2005-03-25 (i486-intel-linux) options wide,nls,dl,al,kan,rh,nd,color,filec। जहां तक ​​इसे गैर-अंतःक्रियात्मक रूप से सोर्स करने की बात है, सोर्स फाइल को पैरेंट फाइल में शामिल किया जाता है जैसे कि यह वास्तव में इसका एक हिस्सा था (इंडिस्टिनिशियली तो) जैसा कि आप अपने मूल प्रश्न में उल्लेख करते हैं। मुझे लगता है कि आपका स्थितिगत पैरामीटर वर्कअराउंड शायद सबसे अच्छा तरीका है। हालाँकि, सामान्य प्रश्न यह है कि "आप ऐसा क्यों करना चाहते हैं" और उत्तर का सामान्य उत्तर है "ऐसा न करें - इसके बजाय ऐसा करें " जहां "यह" अक्सर स्टोर करना है ...
डेनिस विलियमसन

2
@ क्लैके: मुझे लगता है कि बैश के सभी संस्करणों में मैंने 2.05 बी से 4.2.37 तक परीक्षण किया, जिसमें 4.1.9 शामिल है, .और sourceइस संबंध में पहचान के साथ काम किया। ध्यान दें कि फ़ाइल में पहले स्टेटमेंट $_तक पहुंच होनी चाहिए , अन्यथा इसमें पिछली कमांड का अंतिम तर्क होगा। मैं अपने स्वयं के संदर्भ के लिए शेबबैंग को शामिल करना पसंद करता हूं इसलिए मुझे पता है कि यह किस शेल के लिए और संपादक के लिए माना जाता है इसलिए यह सिंटैक्स हाइलाइटिंग का उपयोग करता है।
डेनिस विलियमसन

1
Haha। जाहिर है मैं पहले परीक्षण कर रहा था source, फिर कर रहा था .। मैं अक्षम होने के लिए माफी मांगता हूं। वे वास्तव में समान हैं। वैसे भी, $BASH_SOURCEकाम करता है।
क्लार्क

30

मुझे लगता है कि आप $BASH_SOURCEचर का उपयोग कर सकते हैं । यह वह पथ देता है जिसे निष्पादित किया गया था:

pbm@tauri ~ $ /home/pbm/a.sh 
/home/pbm/a.sh
pbm@tauri ~ $ ./a.sh
./a.sh
pbm@tauri ~ $ source /home/pbm/a.sh 
/home/pbm/a.sh
pbm@tauri ~ $ source ./a.sh
./a.sh

इसलिए अगले चरण में हमें जांचना चाहिए कि क्या पथ सापेक्ष है या नहीं। यदि यह सापेक्ष नहीं है तो सब कुछ ठीक है। अगर यह है तो हम pwdसाथ /और साथ , रास्ते की जाँच कर सकते हैं $BASH_SOURCE


2
और ध्यान दें कि sourceखोज में $PATHअगर दिए गए नाम के एक शामिल नहीं है /। खोज क्रम शेल विकल्पों पर निर्भर करता है, विवरण के लिए मैनुअल देखें।
गिल्स

1
तो, कुछ इस तरह mydir="$(cd "$(dirname "$BASH_SOURCE")"; pwd)"काम करेगा?
केविन कैंटु

धन्यवाद, एक त्वरित और उपयोगी उत्तर। डेनिस ने tcsh जवाब देने के लिए भी हरे रंग की चेक मार्क जीता। @ गिल्स: सही है, मैंने पाया कि प्रलेखन में। सौभाग्य से मेरे उपयोग के मामले में मुझे लगभग निश्चित रूप से इसके बारे में चिंता करने की ज़रूरत नहीं है।
Cascabel

17

यह समाधान केवल बैश करने के लिए लागू होता है न कि tcsh पर। ध्यान दें कि ${BASH_SOURCE[0]}यदि आप किसी फ़ंक्शन के भीतर से पथ खोजने का प्रयास करते हैं, तो आमतौर पर दिया गया उत्तर काम नहीं करेगा।

मैंने इस लाइन को हमेशा काम करने के लिए पाया है, भले ही फ़ाइल को स्क्रिप्ट के रूप में सॉर्ट किया जा रहा हो या चलाया जा रहा हो।

echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}

यदि आप readlinkअपने ऊपर मिलने वाले मार्ग पर, पुनरावर्ती या गैर-पुनरावर्ती रूप से उपयोग किए जाने वाले सिमिलिंक का पालन करना चाहते हैं ।

इसे आज़माने और अन्य प्रस्तावित समाधानों से तुलना करने के लिए यहां एक स्क्रिप्ट है। के रूप में इसे आमंत्रित करें source test1/test2/test_script.shया bash test1/test2/test_script.sh

#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}

cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"

function test_within_func_inside {
    echo ${BASH_SOURCE}
    echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}

echo "Testing within function inside"
test_within_func_inside

echo "Testing within function outside"
test_within_func_outside

#
# Location: test1/test2/func_def.sh
#
function test_within_func_outside {
    echo ${BASH_SOURCE}
    echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}

एक-लाइनर कार्यों का कारण BASH_SOURCEपर्यावरण चर और उसके सहयोगी के उपयोग द्वारा समझाया गया है FUNCNAME

BASH_SOURCE

एक सरणी चर जिसके सदस्य स्रोत फ़ाइलनाम हैं, जहाँ FUNCNAME सरणी चर में संबंधित शेल फ़ंक्शन नाम परिभाषित किए गए हैं। शेल फ़ंक्शन $ {FUNCNAME [$ i]} को $ {BASH_SOURCE [$ i]} में परिभाषित किया गया है और $ {BASH_SOURCE [$ i + 1]} से बुलाया गया है।

FUNCNAME

एक शेल वैरिएबल जिसमें सभी शेल फ़ंक्शंस के नाम हैं जो वर्तमान में निष्पादन कॉल स्टैक में हैं। इंडेक्स 0 वाला तत्व किसी भी वर्तमान में निष्पादित शेल फ़ंक्शन का नाम है। नीचे-सबसे तत्व (उच्चतम सूचकांक वाला) "मुख्य" है। यह चर केवल तब होता है जब शेल फ़ंक्शन निष्पादित हो रहा हो। FUNCNAME को असाइनमेंट का कोई प्रभाव नहीं है और एक त्रुटि स्थिति लौटाता है। यदि FUNCNAME परेशान है, तो यह अपने विशेष गुणों को खो देता है, भले ही यह बाद में रीसेट हो।

इस चर का उपयोग BASH_LINENO और BASH_SOURCE के साथ किया जा सकता है। FUNCNAME के ​​प्रत्येक तत्व में कॉल स्टैक का वर्णन करने के लिए BASH_LINENO और BASH_SOURCE में संबंधित तत्व हैं। उदाहरण के लिए, $ {FUNCNAME [$ i]} को फ़ाइल से $ {BASH_SOURCE [$ i + 1]} लाइन नंबर $ {BASH_LINENO [$ i]} पर कॉल किया गया था। इस जानकारी का उपयोग करके कॉल करने वाला बिलियन वर्तमान कॉल स्टैक को प्रदर्शित करता है।

[स्रोत: बैश मैनुअल]


इस समाधान ने मेरे लिए कोलाहल में काम किया जबकि चयनित उत्तर ने केवल रुक-रुक कर काम किया। मैंने कभी यह पता नहीं लगाया कि यह कभी-कभी क्यों काम करता है और अन्य नहीं (शायद मैं सोर्सिंग शेल पर पर्याप्त ध्यान नहीं दे रहा था)।
जिम

17

संपूर्णता और खोजकर्ताओं के लिए, यहाँ ये है कि ये क्या करते हैं ... यह एक सामुदायिक विकि है, इसलिए अन्य शेल के समकक्षों को जोड़ने के लिए स्वतंत्र महसूस करें (जाहिर है, $ BASH_SOURCE अलग होगा)।

test.sh:

#! /bin/sh
called=$_
echo $called
echo $_
echo $0
echo $BASH_SOURCE

test2.sh:

#! /bin/sh
source ./test.sh

दे घुमा के:

$./test2.sh
./test2.sh
./test2.sh
./test2.sh
./test.sh
$ sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh
./test.sh

पानी का छींटा

$./test2.sh
./test2.sh
./test2.sh
./test2.sh

$/bin/sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh

$

Zsh

$ ./test2.sh
./test.sh
./test.sh
./test.sh

$ zsh test.sh

echo
test.sh

$

1
मुझे समझ में नहीं आता: क्यों called=$_; echo $called; echo $_? क्या यह $_दो बार नहीं छपेगा?
सीरो शांतिली 新疆 改造 iro i 事件

5
@CiroSantilli: हमेशा नहीं, विशेष पैरामीटर पर बैश मैनुअल पढ़ें $_: "शेल स्टार्टअप पर, शेल या शेल स्क्रिप्ट को पर्यावरण या तर्क सूची में पारित किए जाने के लिए उपयोग किए जाने वाले निरपेक्ष पथनाम पर सेट किया जाता है। बाद में, अंतिम तक विस्तारित होता है। विस्तार के बाद, पिछली कमांड पर बहस करें। प्रत्येक कमांड को निष्पादित करने के लिए उपयोग किए गए पूर्ण पथनाम पर सेट है और उस कमांड को निर्यात किए गए वातावरण में रखा गया है। मेल की जाँच करते समय, यह पैरामीटर मेल फ़ाइल का नाम रखता है। "
एडम रोसेनफील्ड

इसके साथ समस्या है खटास वाली फ़ाइल में हेडर है #! /bin/shजो इसे स्रोत के लिए बेकार बनाता है। यह एक नया उदाहरण शुरू करेगा /bin/sh, चर सेट करेगा, फिर उस उदाहरण से बाहर निकलें, जिससे कॉलिंग का अपरिवर्तित होना बंद हो जाएगा।
जेम्सथोमसून 1979

2
@ JamesThomasMoon1979: आप किस बारे में बात कर रहे हैं? #शेल स्क्रिप्ट में शुरुआत के साथ कुछ भी एक टिप्पणी है।  #!(shebang) इसका विशेष अर्थ केवल एक स्क्रिप्ट की पहली पंक्ति के रूप में है जिसे निष्पादित किया जाता है।   किसी फ़ाइल की पहली पंक्ति के रूप में, जो कि दी गई है , यह सिर्फ एक टिप्पणी है।
स्कॉट

13

यह मेरे लिए बाश, पानी का छींटा, ksh, और zsh में काम करता है:

if test -n "$BASH" ; then script=$BASH_SOURCE
elif test -n "$TMOUT"; then script=${.sh.file}
elif test -n "$ZSH_NAME" ; then script=${(%):-%x}
elif test ${0##*/} = dash; then x=$(lsof -p $$ -Fn0 | tail -1); script=${x#n}
else script=$0
fi

echo $script

इन गोले के लिए उत्पादन:

BASH source: ./myscript
ZSH source: ./myscript
KSH source: /home/pbrannan/git/theme/src/theme/web/myscript
DASH source: /home/pbrannan/git/theme/src/theme/web/myscript
BASH: ./myscript
ZSH: ./myscript
KSH: /home/pbrannan/git/theme/src/theme/web/myscript
DASH: ./myscript

मैंने इसे csh / tsh के लिए काम करने की कोशिश की, लेकिन यह बहुत कठिन है; मैं POSIX से चिपका हूं।


1

मैं सामुदायिक विकि उत्तर (शॉन जे। गोफ से) को लेकर थोड़ा भ्रमित था, इसलिए मैंने चीजों को छांटने के लिए एक पटकथा लिखी। के बारे में $_, मुझे यह मिला: एक कमांड के लिए पारित पर्यावरण चर के _रूप में उपयोग । यह एक पर्यावरण चर है, इसलिए इसके मूल्य को गलत तरीके से जांचना आसान है।

नीचे स्क्रिप्ट है, फिर यह आउटपुट है। वे भी इस मुट्ठी में हैं

test-shell-default-variables.sh

#!/bin/bash

# test-shell-default-variables.sh

# Usage examples (you might want to `sudo apt install zsh ksh`):
#
#  ./test-shell-default-variables.sh dash bash
#  ./test-shell-default-variables.sh dash bash zsh ksh
#  ./test-shell-default-variables.sh dash bash zsh ksh | less -R

# `-R` in `less -R` to have less pass escape sequences directly to the terminal
# so we have colors.


# The "invoking with name `sh`" tests are commented because for every shell I
# tested (dash, bash, zsh and ksh), the output was the same as that of dash.

# The `test_expression` function also work with expansion changes. You can try
# lines like `test_expression '{BASH_SOURCE:-$0}'`.

echolor() {
    echo -e "\e[1;36m$@\e[0m"
}

tell_file() {
    echo File \`"$1"\` is:
    echo \`\`\`
    cat "$1"
    echo \`\`\`
    echo
}

SHELL_ARRAY=("$@")

test_command() {
    for shell in "${SHELL_ARRAY[@]}"
    do
        prepare "$shell"
        cmd="$(eval echo $1)"
        # echo "cmd: $cmd"
        printf '%-4s: ' "$shell"
        { env -i $cmd 2>&1 1>&3 | sed 's/^/[err]/'; } 3>&1
        teardown
    done
    echo
}

prepare () {
    shell="$1"
    PATH="$PWD/$shell/sh:$PATH"
}

teardown() {
    PATH="${PATH#*:}"
}


###
### prepare
###
for shell in "${SHELL_ARRAY[@]}"
do
    mkdir "$shell"
    ln -sT "/bin/$shell" "$shell/sh"
done

echo > printer.sh
echo '. ./printer.sh' > sourcer.sh
rm linked.sh &>/dev/null; ln -sT "printer.sh" "linked.sh"

tell_file sourcer.sh

###
### run
###
test_expression() {
    local expr="$1"

    # prepare
    echo "echo $expr" > printer.sh
    tell_file printer.sh

    # run
    cmd='$shell ./printer.sh'
    echolor "\`$cmd\` (simple invocation) ($expr):"
    test_command "$cmd"

    # cmd='sh ./printer.sh'
    # echolor "\`$cmd\` (when executable name is \`sh\`) ($expr):"
    # test_command "$cmd"

    cmd='$shell ./sourcer.sh'
    echolor "\`$cmd\` (via sourcing) ($expr):"
    test_command "$cmd"

    # cmd='sh ./sourcer.sh'
    # echolor "\`$cmd\` (via sourcing, when name is \`sh\`) ($expr):"
    # test_command "$cmd"

    cmd='$shell ./linked.sh'
    echolor "\`$cmd\` (via symlink) ($expr):"
    test_command "$cmd"

    # cmd='sh ./linked.sh'
    # echolor "\`$cmd\` (via symlink, when name is \`sh\`) ($expr):"
    # test_command "$cmd"

    echolor "------------------------------------------"
    echo
}

test_expression '$BASH_SOURCE'
test_expression '$0'
test_expression '$(/bin/true x y; true a b c; echo $_)' # Rq: true is a builtin
test_expression '$_'

###
### teardown
###
for shell in "${SHELL_ARRAY[@]}"
do
    rm "$shell/sh"
    rm -d "$shell"
done

rm sourcer.sh
rm linked.sh
rm printer.sh

का आउटपुट ./test-shell-default-variables.sh {da,ba,z,k}sh

File `sourcer.sh` is:
```
. ./printer.sh
```

File `printer.sh` is:
```
echo $BASH_SOURCE
```

`$shell ./printer.sh` (simple invocation) ($BASH_SOURCE):
dash: 
bash: ./printer.sh
zsh : 
ksh : 

`$shell ./sourcer.sh` (via sourcing) ($BASH_SOURCE):
dash: 
bash: ./printer.sh
zsh : 
ksh : 

`$shell ./linked.sh` (via symlink) ($BASH_SOURCE):
dash: 
bash: ./linked.sh
zsh : 
ksh : 

------------------------------------------

File `printer.sh` is:
```
echo $0
```

`$shell ./printer.sh` (simple invocation) ($0):
dash: ./printer.sh
bash: ./printer.sh
zsh : ./printer.sh
ksh : ./printer.sh

`$shell ./sourcer.sh` (via sourcing) ($0):
dash: ./sourcer.sh
bash: ./sourcer.sh
zsh : ./printer.sh
ksh : ./sourcer.sh

`$shell ./linked.sh` (via symlink) ($0):
dash: ./linked.sh
bash: ./linked.sh
zsh : ./linked.sh
ksh : ./linked.sh

------------------------------------------

File `printer.sh` is:
```
echo $(/bin/true x y; true a b c; echo $_)
```

`$shell ./printer.sh` (simple invocation) ($(/bin/true x y; true a b c; echo $_)):
dash: 
bash: c
zsh : c
ksh : 

`$shell ./sourcer.sh` (via sourcing) ($(/bin/true x y; true a b c; echo $_)):
dash: 
bash: c
zsh : c
ksh : 

`$shell ./linked.sh` (via symlink) ($(/bin/true x y; true a b c; echo $_)):
dash: 
bash: c
zsh : c
ksh : 

------------------------------------------

File `printer.sh` is:
```
echo $_
```

`$shell ./printer.sh` (simple invocation) ($_):
dash: 
bash: bash
zsh : 
ksh : 

`$shell ./sourcer.sh` (via sourcing) ($_):
dash: 
bash: bash
zsh : ./printer.sh
ksh : 

`$shell ./linked.sh` (via symlink) ($_):
dash: 
bash: bash
zsh : 
ksh : 

------------------------------------------

हमने क्या सीखा?

$BASH_SOURCE

  • $BASH_SOURCE काम करता है और केवल बकवास में काम करता है।
  • एकमात्र अंतर $0तब है जब वर्तमान फ़ाइल को किसी अन्य फ़ाइल द्वारा सॉर्ट किया गया था। उस स्थिति में, $BASH_PROFILEइसमें खट्टी फाइल के बजाय खट्टी फाइल का नाम होता है।

$0

  • Zsh में, बैश में $0समान मूल्य है $BASH_SOURCE

$_

  • $_ डैश और ksh से अछूता रह गया है।
  • बैश और zsh में, $_अंतिम कॉल के अंतिम तर्क के लिए निर्णय लेता है ।
  • बैश $_"बैश" के लिए इनिशियलाइज़ करता है।
  • zsh $_अछूता छोड़ देता है । (जब सोर्सिंग, यह "अंतिम तर्क" नियम का परिणाम है)।

सिमलिंक

  • जब किसी स्क्रिप्ट को सिम्लिंक के माध्यम से कॉल किया जाता है, तो किसी भी चर में लिंक का कोई संदर्भ नहीं होता है, केवल उसका नाम होता है।

क्ष

  • उन परीक्षणों के बारे में, ksh डैश की तरह व्यवहार करता है।

  • जब बैश या ज़ीश को एक सिमिलिंक के माध्यम से बुलाया जाता है sh, तो उन परीक्षणों के बारे में, यह डैश की तरह व्यवहार करता है।


0

यदि आप केवल बयान लिख सकते हैं तो अपनी स्क्रिप्ट को उपयोग करने के बजाय बैश- और ज़श-संगत दोनों बनाने के लिए ${BASH_SOURCE[0]:-${(%):-%x}}। परिणामी मान BASH_SOURCE[0]तब लिया जाएगा जब इसे परिभाषित किया जाएगा, और ${(%):-%x}}जब BASH_SOURCE [0] को परिभाषित नहीं किया जाएगा।


0

tl; डॉ। script=$(readlink -e -- "${BASH_SOURCE}") (स्पष्ट रूप से बैश के लिए)


$BASH_SOURCE परीक्षण के मामलों

फ़ाइल दी गई /tmp/source1.sh

echo '$BASH_SOURCE '"(${BASH_SOURCE})"
echo 'readlink -e $BASH_SOURCE'\
     "($(readlink -e -- "${BASH_SOURCE}"))"

source विभिन्न शिष्टाचार में फ़ाइल

source से /tmp

$> cd /tmp

$> source source1.sh
$BASH_SOURCE (source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

$> source ./source1.sh
$BASH_SOURCE (./source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

$> source /tmp/source1.sh
$BASH_SOURCE (/tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

source से /

cd /
$> source /tmp/source1.sh
$0 (bash)
$BASH_SOURCE (/tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

sourceविभिन्न रिश्तेदार रास्तों से /tmp/aऔर/var

$> cd /tmp/a

$> source ../source1.sh
$BASH_SOURCE (../source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

$> cd /var

$> source ../tmp/source1.sh
$BASH_SOURCE (../tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

के बारे में $0

सभी मामलों में, यदि स्क्रिप्ट में कमांड जोड़ी गई थी

echo '$0 '"(${0})"

फिर sourceस्क्रिप्ट हमेशा छपी

$0 (bash)

हालाँकि , यदि स्क्रिप्ट चलाई गई थी , जैसे

$> bash /tmp/source1.sh

तब $0स्ट्रिंग मान होगा /tmp/source1.sh

$0 (/tmp/source1.sh)
$BASH_SOURCE (/tmp/source1.sh)
readlink -e $BASH_SOURCE (/tmp/source1.sh)

0

इस उत्तर में बताया गया है कि कैसे lsofऔर थोडा grep मैजिक एक ही चीज़ है जो tcsh के तहत नेस्टेड सॉर्ट की गई फ़ाइलों के लिए काम करने का एक मौका खड़ा करता है:

/usr/sbin/lsof +p $$ | grep -oE /.\*source_me.tcsh

-2
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0%/*}";;
  *) scriptdir="$wdir/${0#./}"; scriptdir="${scriptdir%/*}";;
esac
echo "$scriptdir"

हो सकता है कि यह सिमिलिंक या सॉर्स्ड फाइलों के साथ काम न करे बल्कि सामान्य फाइलों के लिए काम करे। संदर्भ के रूप में लिया जाता है। @kenorb नहीं dirname, readlink, BASH_SOURCE।


1
इस प्रश्न में समझाया गया था कि $0आपको वर्तमान में चल रही स्क्रिप्ट के बारे में जानकारी मिलती है , न कि एक खटास।
स्कॉट

-3

वास्तव में, "dirname $ 0" आपको स्क्रिप्ट के लिए रास्ता देगा, लेकिन आपको इसे थोड़ा व्याख्या करना होगा:

$ cat bash0
#!/bin/bash
echo \$0=$0
dirname $0
$ bash0    # "." appears in PATH right now.
$0=./bash0
.
$ ./bash0
$0=./bash0
.
$ $PWD/bash0
$0=/home/00/bediger/src/ksh/bash0
/home/00/bediger/src/ksh
$ $PWD/../ksh/bash0
$0=/home/00/bediger/src/ksh/../ksh/bash0
/home/00/bediger/src/ksh/../ksh
$ ../ksh/bash0
$0=../ksh/bash0
../ksh

आपको संभालने के लिए तैयार करना होगा "।" कुछ सामान्य परिस्थितियों में निर्देशिका नाम के रूप में। मैं थोड़ा प्रयोग करूंगा, क्योंकि मुझे याद है कि बिल्ट-इन करने के लिए dirname बिलकुल अलग चीज़ है जब ""। पथ में प्रकट होता है।


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