सबसे सामान्य मामलों में, $0स्क्रिप्ट के लिए एक पथ, निरपेक्ष या सापेक्ष होगा, इसलिए
script_path=$(readlink -e -- "$0")
(यह मानते हुए कि एक readlinkकमांड है और यह समर्थन करता है -e) आम तौर पर स्क्रिप्ट के लिए कैनोनिकल निरपेक्ष पथ प्राप्त करने का एक अच्छा तरीका है।
$0 इंटरप्रेटर में पास किए गए स्क्रिप्ट को निर्दिष्ट करने वाले तर्क से असाइन किया गया है।
उदाहरण के लिए:
the-shell -shell-options the/script its args
$0हो जाता है the/script।
जब आप दौड़ते हैं:
the/script its args
आपका खोल एक करेगा:
exec("the/script", ["the/script", "its", "args"])
यदि स्क्रिप्ट में #! /bin/sh -उदाहरण के लिए वह धमाकेदार है, तो सिस्टम उसे बदल देगा:
exec("/bin/sh", ["/bin/sh" or "the/script", "-", "the/script", "its", "args"])
(यदि इसमें वह-बैंग शामिल नहीं है, या अधिक आम तौर पर यदि सिस्टम एक ENOEXEC त्रुटि देता है, तो आपका शेल जो कि एक ही काम करेगा)
कुछ सिस्टम पर सेतु / सेटगिड स्क्रिप्ट के लिए एक अपवाद है, जहां सिस्टम स्क्रिप्ट को कुछ पर खोल देगा fd xऔर इसके बजाय चलाएगा:
exec("/bin/sh", ["/bin/sh" or "the/script", "-", "/dev/fd/x", "its", "args"])
दौड़ की स्थिति से बचने के लिए (जिसमें मामला $0शामिल होगा /dev/fd/x)।
अब, आप यह तर्क दे सकते हैं कि /dev/fd/x यह स्क्रिप्ट का एक मार्ग है। ध्यान दें कि यदि आप से पढ़ते हैं $0, तो आप इनपुट का उपभोग करते हुए स्क्रिप्ट को तोड़ देंगे।
अब, अगर स्क्रिप्ट कमांड नाम को आमंत्रित किया जाता है तो इसमें कोई अंतर नहीं होता है। में:
the-script its args
आपका खोल ऊपर दिखेगा the-scriptमें $PATH। $PATHकुछ निर्देशिकाओं के लिए निरपेक्ष या सापेक्ष (रिक्त स्ट्रिंग सहित) पथ हो सकते हैं। उदाहरण के लिए, यदि वर्तमान निर्देशिका में $PATHशामिल है /bin:/usr/bin:और the-scriptपाया जाता है, तो शेल एक करेगा:
exec("the-script", ["the-script", "its", "args"])
जो बन जाएगा:
exec("/bin/sh", ["/bin/sh" or "the-script", "-", "the-script", "its", "args"]
या यदि यह पाया जाता है /usr/bin:
exec("/usr/bin/the-script", ["the-script", "its", "args"])
exec("/bin/sh", ["/bin/sh" or "the-script" or "/usr/bin/the-script",
"-", "/usr/bin/the-script", "its", "args")
उपर्युक्त कोने के मामले को छोड़कर उन सभी मामलों में, $0स्क्रिप्ट में एक पथ (पूर्ण या सापेक्ष) होगा।
अब, एक स्क्रिप्ट के रूप में भी कहा जा सकता है:
the-interpreter the-script its args
जब the-scriptऊपर से स्लैश वर्ण नहीं होते हैं, तो व्यवहार शेल से शेल में थोड़ा भिन्न होता है।
पुराने एटी एंड टी kshकार्यान्वयन वास्तव में स्क्रिप्ट को बिना शर्त के देख रहे थे $PATH(जो वास्तव में बग और सेतु लिपियों के लिए एक सुरक्षा छेद $0था ), इसलिए वास्तव में स्क्रिप्ट में एक पथ शामिल नहीं था जब तक कि $PATHवास्तव the-scriptमें वर्तमान निर्देशिका में खोजने के लिए लुकअप नहीं हुआ था ।
यदि यह पठनीय है, तो नया AT & T वर्तमान निर्देशिका में kshप्रयास और व्याख्या करेगा the-script। यदि नहीं यह एक पठनीय के लिए देखने हैं और निष्पादन the-script में $PATH।
इसके लिए bash, यह जाँच करता है कि the-scriptक्या वर्तमान निर्देशिका में है (और एक टूटी हुई सिमलिंक नहीं है) और यदि नहीं, तो एक पठनीय (आवश्यक रूप से निष्पादन योग्य नहीं) the-scriptके लिए खोज $PATH।
zshमें shअनुकरण की तरह करना होगा bash, सिवाय इसके कि यदि the-scriptवर्तमान निर्देशिका में एक टूट सिमलिंक है, यह एक के लिए खोज नहीं होगा the-scriptमें $PATHहै और इसके बजाय एक त्रुटि रिपोर्ट करेंगे।
अन्य सभी बॉर्न-जैसे गोले the-scriptऊपर नहीं दिखते $PATH।
वैसे भी उन सभी गोले के लिए, यदि आप पाते हैं कि $0इसमें शामिल नहीं है /और पठनीय नहीं है, तो संभवतः इसे ऊपर देखा गया है $PATH। फिर, जैसा कि फ़ाइलों के $PATHनिष्पादन योग्य होने की संभावना है, यह संभवतः command -v -- "$0"अपने पथ को खोजने के लिए उपयोग करने के लिए एक सुरक्षित सन्निकटन है (हालांकि यह काम नहीं करेगा यदि $0शेल शेल या कीवर्ड (अधिकांश गोले में) का नाम भी हो।
इसलिए यदि आप वास्तव में उस मामले के लिए कवर करना चाहते हैं, तो आप इसे लिख सकते हैं:
progname=$0
[ -r "$progname" ] || progname=$(
IFS=:; set -f
for i in ${PATH-$(getconf PATH)}""; do
case $i in
"") p=$progname;;
*/) p=$i$progname;;
*) p=$i/$progname
esac
[ -r "$p" ] && exec printf '%s\n' "$p"
done
exit 1
) && progname=$(readlink -e -- "$progname") ||
progname=unknown
( ""संलग्न करने $PATHके लिए एक अनुगामी खाली तत्व को गोले के साथ संरक्षित करना है, जो विभाजक के बजाय सीमांकक के$IFS रूप में कार्य करता है )।
अब, एक स्क्रिप्ट को लागू करने के लिए अधिक गूढ़ तरीके हैं। एक कर सकता है:
the-shell < the-script
या:
cat the-script | the-shell
उस मामले में, $0पहला तर्क होगा ( argv[0]) कि इंटरप्रेटर प्राप्त हुआ (ऊपर the-shell, लेकिन वह कुछ भी हो सकता है, हालांकि आम तौर पर या तो आधार या उस दुभाषिया के लिए एक रास्ता)।
यह पता लगाना कि आप उस स्थिति में हैं, जिसके आधार पर मूल्य $0विश्वसनीय नहीं है। आप ps -o args= -p "$$"एक सुराग पाने के लिए आउटपुट को देख सकते हैं। पाइप के मामले में, कोई वास्तविक तरीका नहीं है जिससे आप स्क्रिप्ट पर वापस जा सकते हैं।
एक भी कर सकता है:
the-shell -c '. the-script' blah blih
फिर, zsh(और बॉर्न शेल के कुछ पुराने कार्यान्वयन को छोड़कर ), $0होगा blah। फिर, उन गोले में स्क्रिप्ट के रास्ते पर आना मुश्किल है।
या:
the-shell -c "$(cat the-script)" blah blih
आदि।
यह सुनिश्चित करने के लिए कि आपके पास अधिकार है $progname, आप इसमें एक विशिष्ट स्ट्रिंग की खोज कर सकते हैं:
progname=$0
[ -r "$progname" ] || progname=$(
IFS=:; set -f
for i in ${PATH-$(getconf PATH)}:; do
case $i in
"") p=$progname;;
*/) p=$i$progname;;
*) p=$i/$progname
esac
[ -r "$p" ] && exec printf '%s\n' "$p"
done
exit 1
) && progname=$(readlink -e -- "$progname") ||
progname=unknown
[ -f "$progname" ] && grep -q 7YQLVVD3UIUDTA32LSE8U9UOHH < "$progname" ||
progname=unknown
लेकिन फिर से मुझे नहीं लगता कि यह प्रयास के लायक है।
$0स्क्रिप्ट के अलावा कुछ और है, जो प्रश्न शीर्षक का जवाब देता है। हालांकि, मैं उन स्थितियों में भी दिलचस्पी रखता हूं जहां$0स्क्रिप्ट ही है, लेकिन निर्देशिका शामिल नहीं है। विशेष रूप से, मैं SO उत्तर पर की गई टिप्पणी को समझने की कोशिश कर रहा हूं।