आपको इसे चलाने के लिए निष्पादन योग्य या स्क्रिप्ट नाम से पहले (/-स्लैश) की आवश्यकता क्यों है?


288

बैश में स्क्रिप्ट चलाते समय, मुझे ./शुरुआत में लिखना होगा :

$ ./manage.py syncdb

यदि मैं नहीं करता, तो मुझे एक त्रुटि संदेश मिलता है:

$ manage.py syncdb
-bash: manage.py: command not found

इसका क्या कारण है? मैंने सोचा कि .वर्तमान फ़ोल्डर के लिए एक उपनाम है, और इसलिए इन दो कॉल के बराबर होना चाहिए।

मुझे यह भी समझ में नहीं आता है कि ./आवेदन चलाते समय मुझे इसकी आवश्यकता क्यों नहीं है , जैसे:

user:/home/user$ cd /usr/bin
user:/usr/bin$ git

(जो बिना रुके चलता है ./)


4
इस मामले पर यह अब तक का सबसे अच्छा दस्तावेज़ है: linfo.org/dot_slash.html
21

जवाबों:


307

क्योंकि यूनिक्स पर, आमतौर पर, वर्तमान निर्देशिका अंदर नहीं है $PATH

जब आप एक कमांड टाइप करते हैं तो शेल निर्देशिकाओं की एक सूची दिखता है, जैसा कि PATHचर द्वारा निर्दिष्ट किया गया है। वर्तमान निर्देशिका उस सूची में नहीं है।

उस सूची में वर्तमान निर्देशिका नहीं होने का कारण सुरक्षा है।

मान लें कि आप रूट हैं और slइसके बजाय किसी अन्य उपयोगकर्ता की निर्देशिका में जाएं और टाइप करें ls। यदि वर्तमान निर्देशिका में है PATH, तो शेल slउस निर्देशिका में कार्यक्रम को निष्पादित करने का प्रयास करेगा (क्योंकि कोई अन्य slकार्यक्रम नहीं है)। वह slकार्यक्रम दुर्भावनापूर्ण हो सकता है।

इसके साथ काम करता है ./क्योंकि POSIX निर्दिष्ट करता है कि एक कमांड नाम जिसमें /एक खोज के रूप में दबाने के लिए इसे सीधे फ़ाइल नाम के रूप में उपयोग किया जाएगा $PATH। आप एक ही प्रभाव के लिए पूर्ण पथ का उपयोग कर सकते थे, लेकिन ./यह छोटा और लिखने में आसान है।

संपादित करें

वह slहिस्सा सिर्फ एक उदाहरण था। PATHक्रमिक रूप से निर्देशिकाओं की खोज की जाती है और जब एक मैच किया जाता है तो उस कार्यक्रम को निष्पादित किया जाता है। तो, कैसे PATHदिखता है पर निर्भर करता है, एक सामान्य कमांड टाइप करना या चालू निर्देशिका में प्रोग्राम को चलाने के लिए पर्याप्त नहीं हो सकता है।


47
आपको कुछ भी गलत करने की आवश्यकता नहीं है। उपयोगकर्ता ने केवल एक दुर्भावनापूर्ण पैकेज डाउनलोड किया होगा जिसमें एक lsनिष्पादन योग्य है।
जूलियानो

13
बस सभी को यह कहते हुए एक नोट। यह केवल यूनिक्स और विंडोज में नहीं है, यह .\my.bat
पॉवर्सशेल

1
@ एगॉन एर्ग, मैंने कहा "एक उपनाम नहीं है", जब कि "सख्ती से एक उपनाम" होना चाहिए था।
चार्ल्स डफी

4
यह एक बहुत ही उपयोगी व्याख्या थी। 20+ साल पहले जब मैंने DOS के साथ थोड़ा काम किया, तो मुझे लगता है कि CMD वर्तमान डायरेक्टरी को जांचेगा, जब वह PATH होगा, इसलिए लिनक्स का व्यवहार मुझसे अपेक्षित नहीं था, लेकिन यह बहुत मायने रखता है।
टेकब्राट

2
@cnicutar: दिलचस्प बात यह है कि आज मैंने पाया कि slभाप लोकोमोटिव नामक एक कमांड है जो डिफ़ॉल्ट रूप से उपलब्ध नहीं है
;;

51

जब बैश कमांड लाइन की व्याख्या करता है, तो यह वातावरण चर में वर्णित स्थानों में कमांड की तलाश करता है $PATH। इसे देखने के लिए टाइप करें:

echo $PATH

आपके पास कॉलोनों द्वारा अलग किए गए कुछ रास्ते होंगे। जैसा कि आप देखेंगे कि वर्तमान पथ .आमतौर पर नहीं है $PATH। यदि वर्तमान निर्देशिका में है तो Bash आपकी कमांड नहीं ढूंढ सकता है। आप इसे बदलकर कर सकते हैं:

PATH=$PATH:.

यह पंक्ति वर्तमान निर्देशिका को जोड़ती है $PATHजिससे आप कर सकते हैं:

manage.py syncdb

यह अनुशंसित नहीं है क्योंकि इसमें सुरक्षा मुद्दा है, साथ ही आप अजीब व्यवहार कर सकते हैं, जैसा .कि आप जिस निर्देशिका में हैं , उसमें भिन्नता है :)

से बचें:

PATH=.:$PATH

जैसा कि आप कुछ मानक कमांड "मुखौटा" कर सकते हैं और सुरक्षा उल्लंघन के लिए दरवाजा खोल सकते हैं :)

केवल मेरे दो सेंट्स।


42

आपकी स्क्रिप्ट, जब आपके होम डायरेक्टरी में नहीं मिलेगी जब शेल $PATHआपकी स्क्रिप्ट को खोजने के लिए पर्यावरण चर को देखता है ।

./कहते हैं, 'के बजाय मेरी स्क्रिप्ट के लिए मौजूदा निर्देशिका में देखो सभी निर्देशिकाओं में निर्दिष्ट को देख $PATH'।


5

जब आप 'को शामिल करते हैं।' आप अनिवार्य रूप से निष्पादन योग्य बैश स्क्रिप्ट को "पूर्ण पथ" दे रहे हैं, इसलिए आपके शेल को आपके पैट चर की जांच करने की आवश्यकता नहीं है। के बिना '।' आपका शेल आपके PATH वैरिएबल में दिखेगा (जिसे आप यह देखकर चला सकते हैं कि echo $PATHआपके PATH के किसी भी फोल्डर में आपके द्वारा टाइप की गई कमांड रहती है। यदि ऐसा नहीं है (जैसा कि मैनेजमेक्स के साथ होता है) तो यह कहता है। फ़ाइल नहीं मिल रही है। यह आपके पीएटीएच पर वर्तमान निर्देशिका को शामिल करने के लिए बुरा व्यवहार माना जाता है, जिसे यहां काफी अच्छी तरह से समझाया गया है: http://www.faqs.org/faqs/unix-faq/faq/part2/section- 13.html


2

विंडोज के विपरीत * निक्स पर, वर्तमान निर्देशिका आमतौर पर आपके $PATHचर में नहीं होती है। इसलिए कमांड निष्पादित करते समय वर्तमान निर्देशिका को नहीं खोजा जाता है। आप की जरूरत नहीं है ./क्योंकि इन आवेदनों अनुप्रयोगों को चलाने के लिए कर रहे हैं अपने $ पथ में; सबसे अधिक संभावना है कि वे /binया में हैं /usr/bin


1

इस प्रश्न के पहले से ही कुछ भयानक उत्तर हैं, लेकिन मैं इसे जोड़ना चाहता था, यदि आपका निष्पादन योग्य पथ पर है, और आपको चलाने पर बहुत अलग आउटपुट मिलते हैं

./executable

यदि आप दौड़ते हैं तो आप इसे प्राप्त कर सकते हैं

executable

(मान लें कि आप एक और नहीं के साथ त्रुटि संदेशों में चलते हैं), तो समस्या यह हो सकती है कि आपके पास आपकी मशीन पर निष्पादन योग्य के दो अलग-अलग संस्करण हैं: एक पथ पर, और दूसरा नहीं।

इसे चलाकर देखें

जो निष्पादन योग्य है

तथा

whereis executable

इसने मेरे मुद्दों को तय किया ... मेरे पास निष्पादन योग्य के तीन संस्करण थे, जिनमें से केवल एक को पर्यावरण के लिए सही ढंग से संकलित किया गया था।


0

/पोसिट पेट नियम के लिए तर्क

इस नियम का उल्लेख किया गया था: आपको इसे चलाने के लिए निष्पादन योग्य या लिपि नाम से पहले / (डॉट-स्लेश) की आवश्यकता क्यों है? लेकिन मैं यह बताना चाहूंगा कि मुझे क्यों लगता है कि अधिक विस्तार से एक अच्छा डिजाइन है।

सबसे पहले, नियम का एक स्पष्ट पूर्ण संस्करण है:

  • यदि पथ समाहित है /(उदाहरण ./someprogके लिए /bin/someprog, ./bin/someprog): CWD का उपयोग किया जाता है और PATH नहीं है
  • यदि पथ शामिल नहीं है /(उदाहरण के लिए someprog): पथ का उपयोग किया जाता है और CWD नहीं है

अब, मान लीजिए कि चल रहा है:

someprog

खोज होगा:

  • पहले CWD के सापेक्ष
  • PATH के सापेक्ष

फिर, यदि आप /bin/someprogअपने डिस्ट्रो से भागना चाहते थे , और आपने किया:

someprog

यह कभी-कभी काम करेगा, लेकिन दूसरों को यह विफल होगा, क्योंकि आप एक निर्देशिका में हो सकते हैं जिसमें एक और असंबंधित someprogकार्यक्रम शामिल है।

इसलिए, आप जल्द ही सीखेंगे कि यह विश्वसनीय नहीं है, और जब आप पैथ का उपयोग करना चाहते हैं, तो आप हमेशा पूर्ण रास्तों का उपयोग करते हुए समाप्त करेंगे, इसलिए पीएटीएच के उद्देश्य को हरा सकते हैं।

ऐसा इसलिए भी है क्योंकि आपके PATH में सापेक्ष पथ होना वास्तव में एक बुरा विचार है। मैं कर रहा हूँ , आप देखnode_modules/bin

इसके विपरीत, मान लें कि चल रहा है:

./someprog

खोज करेंगे:

  • पहले PATH के सापेक्ष
  • CWD के सापेक्ष

फिर, यदि आपने अभी एक स्क्रिप्ट someprogको एक रिपॉजिटरी से डाउनलोड किया है और इसे CWD से चलाना चाहते हैं, तो आपको कभी भी यकीन नहीं होगा कि यह वास्तविक प्रोग्राम है जो चलेगा, क्योंकि शायद आपके डिस्ट्रो में एक:

/bin/someprog

जो आपके द्वारा पिछले साल क्रिसमस के बाद बहुत अधिक पीने के बाद स्थापित किए गए कुछ पैकेज में से है।

इसलिए, एक बार फिर, आपको यह जानने के लिए मजबूर किया जाएगा कि आप क्या कर रहे हैं, यह जानने के लिए पूर्ण पथों के साथ CWD के सापेक्ष हमेशा स्थानीय स्क्रिप्ट चलाएं:

"$(pwd)/someprog"

जो बेहद कष्टप्रद होगा।

एक और नियम जिसके साथ आने के लिए आपको लुभाया जा सकता है:

सापेक्ष पथ केवल पथ का उपयोग करते हैं, पूर्ण पथ केवल CWD का

लेकिन एक बार फिर यह उपयोगकर्ताओं को गैर-पथ स्क्रिप्ट के लिए निरपेक्ष पथ का उपयोग करने के लिए मजबूर करता है "$(pwd)/someprog"

/पथ खोज नियम समस्या के बारे में का हल याद करने के लिए एक सरल प्रदान करता है:

  • स्लैश: उपयोग नहीं करते PATH
  • कोई स्लैश नहीं: केवल उपयोग करें PATH

जो यह बताता है कि आप जो भी चला रहे हैं उसे हमेशा जानना आसान है, इस तथ्य पर भरोसा करके कि वर्तमान निर्देशिका में फ़ाइलों को ./somefileया तो व्यक्त किया जा सकता है somefile, और इसलिए यह उनमें से एक को विशेष अर्थ देता है।

कभी-कभी, थोड़ा कष्टप्रद होता है कि आप some/progरिश्तेदार के लिए खोज नहीं कर सकते हैं PATH, लेकिन मुझे इसका कोई हल नहीं दिखता है।


-1

जब स्क्रिप्ट पथ में ऐसा करने के लिए आवश्यक नहीं है। अधिक जानकारी के लिए पढ़ें http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html


5
... FYI करें, irc.freenode.org पर # बैग में, हम लगातार गलतफहमी को ठीक कर रहे हैं जो लोगों ने टीएलडीपी (विशेष रूप से उन्नत बैश गाइड) से सीखा है। जैसे, वहाँ लोगों को निर्देशित करना ... शायद आदर्श नहीं है। (हमारा पसंदीदा परिचयात्मक दस्तावेज mywiki.wooledge.org/BashGuide है )
चार्ल्स डफी

-2

प्रश्न पर सभी के पास शानदार उत्तर हैं, और यह केवल तब लागू होता है जब इसे वर्तमान निर्देशिका पर तब तक नहीं चलाया जाता जब तक कि आप पूर्ण पथ को शामिल नहीं करते। मेरे नमूने नीचे देखें।

इसके अलावा, डॉट (स्लैश) ने मेरे लिए समझ में आता है जब मैंने चाइल्ड फोल्डर tmp2 (/ tmp / tmp2) पर कमांड किया है और यह (डबल डॉट-स्लैश) का उपयोग करता है।

नमूना:

[fifiip-172-31-17-12 tmp]$ ./StackO.sh

Hello Stack Overflow

[fifi@ip-172-31-17-12 tmp]$ /tmp/StackO.sh

Hello Stack Overflow

[fifi@ip-172-31-17-12 tmp]$ mkdir tmp2

[fifi@ip-172-31-17-12 tmp]$ cd tmp2/

[fifi@ip-172-31-17-12 tmp2]$ ../StackO.sh

Hello Stack Overflow
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.