मुझे वर्तमान निर्देशिका में प्रोग्राम निष्पादित करने से पहले `/ 'टाइप करने की आवश्यकता क्यों है?


92

a.outउबंटू टर्मिनल का उपयोग करते हुए , सी प्रोग्राम को निष्पादित करते समय , मुझे केवल लिखने के बजाय हमेशा ./पहले टाइप करने की आवश्यकता क्यों है ? क्या इसका कोई हल है?a.outa.out




जवाबों:


119

जब आप किसी प्रोग्राम का नाम टाइप करते हैं जैसे a.outकि सिस्टम आपके PATH में फाइल की तलाश करता है। मेरे सिस्टम पर, PATH सेट है

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

तुम्हारा भी शायद ऐसा ही है। जांच करने के लिए, echo $PATHएक टर्मिनल में दर्ज करें ।

सिस्टम दिए गए आदेश में इन निर्देशिकाओं के माध्यम से देखता है और अगर यह नहीं मिल सकता है तो प्रोग्राम एक command not foundत्रुटि पैदा करता है ।

कमांड को ./प्रभावी ढंग से प्रस्तुत करते हुए कहते हैं "पाथ के बारे में भूल जाओ, मैं चाहता हूं कि आप केवल वर्तमान निर्देशिका में दिखें"।

इसी तरह आप सिस्टम को केवल किसी अन्य विशिष्ट स्थान पर देखने के लिए कह सकते हैं, जैसे कि किसी रिश्तेदार या निरपेक्ष मार्ग के साथ कमांड को प्रस्तुत करना:

../मूल निर्देशिका में इसका अर्थ है जैसे मूल निर्देशिका ../helloमें हैलो की तलाश करें।

./Debug/hello: " helloमेरी वर्तमान निर्देशिका के डीबग उपनिर्देशिका में देखें।"

या /bin/ls: " lsनिर्देशिका में देखें /bin"

डिफ़ॉल्ट रूप से, वर्तमान निर्देशिका पथ में नहीं है क्योंकि इसे सुरक्षा जोखिम माना जाता है। देखें क्यों है डिफ़ॉल्ट रूप से पथ में नहीं है? क्यों के लिए Superuser पर

वर्तमान निर्देशिका को आपके PATH में जोड़ना संभव है, लेकिन लिंक किए गए प्रश्न में दिए गए कारणों के लिए, मैं इसकी सिफारिश नहीं करूंगा।


25
इस। +1 इस उत्तर में उल्लिखित सुरक्षा जोखिम के कारण आपके (अन्य 2 उत्तरों के रूप में वर्तमान में सुझाए गए) को जोड़ें । .PATH
दिन

8
यह भी ध्यान देने योग्य हो सकता है कि .यहाँ कुछ खास नहीं है, आप एक पूर्ण या रिश्तेदार पथ का उपयोग कर सकते हैं जैसे निष्पादन योग्य /home/user/foo/a.outया./build/a.out
tobyodavies

@tobyodavies; वास्तव .में विशेष है क्योंकि इसका मतलब है "मेरी वर्तमान निर्देशिका" इसलिए कोई भी निर्देशिका हो सकती है जो उपयोगकर्ता उन्हें पढ़ने और विशेषाधिकारों को निष्पादित करने में स्वयं को पाता है। यह एक विशिष्ट पूर्ण योग्य पथ को जोड़ने की तुलना में संभावित रूप से अधिक खतरनाक है।
वारेन हिल

@ArrenHill जब इसे अपने पथ पर जोड़ने पर विचार करता है, तो हाँ यह बिलकुल अलग है। हालांकि बैश सिंटैक्स के संदर्भ में, .कोई विशेष स्थिति नहीं रखता है, यह सिर्फ एक रास्ता है जो बस के साथ शुरू हो सकता है /और ./blahबस के साथ catया grepबैश प्रॉम्प्ट के साथ काम करेगा ।
तोबोडावीज

@tobyodavies: ठीक है, मैंने आपकी बात को शामिल करने के लिए अपना उत्तर संपादित किया है।
वारेन हिल

24

इतना सरल होने का कारण।

मान लीजिए कि आपके पास वर्तमान निर्देशिका में एप्लिकेशन के समान नाम वाला एक कमांड है। फिर शेल में कमांड चलाने से बिल्ट-इन कमांड के बजाय आपके ऐप को इनवॉइस किया जाएगा । यह एक सुरक्षा चिंता का विषय होगा अगर कुछ और नहीं।

./सामने उपयोग करने की आवश्यकता होने पर, शेल जानता है कि आप दिए गए नाम के साथ आवेदन को निष्पादित करना चाहते हैं, न कि उस नाम के साथ अंतर्निहित कमांड।


1
आपकी व्याख्या भ्रामक है, शेल और निष्पादन योग्य में अंतर्निहित आदेशों के बीच एक अंतर है जो PATH चर के माध्यम से सुलभ है। वास्तव में आपके जवाब के रूप में मैं जितना अधिक पढ़ता हूं वह अधिक गलत लगता है।
अहमद मसूद

16

./उन फ़ाइलों को निष्पादित करता है जो आपके में नहीं हैं $PATH, बल्कि यह फ़ाइल को वर्तमान निर्देशिका (या किसी अन्य ./home/stefano/script.sh) के माध्यम से निष्पादित करती है । अब, पीएटीएच एक पर्यावरण चर है जिसमें सभी स्थानों पर बैश निष्पादन योग्य कार्यक्रमों की तलाश कर सकते हैं, उनके लिए पूर्ण (पूर्ण) पथ के बिना।

गलत फ़ाइल चलाने से बचने के लिए इस पृथक्करण की आवश्यकता है। यानी अगर आपके पास lsअपने घर निर्देशिका में एक फ़ाइल है , तो यह आपके PATH में नहीं होने के कारण इसे असली के साथ भ्रमित करने से रोक देगा ls। पथ परिवर्तन खोज क्रम को भी परिभाषित करता है:

  • जब आप एक कमांड चलाते हैं, या एक प्रोग्राम एक execसिसकॉल बनाने की कोशिश करता है (कर्नेल की एक विशेष विधि, प्रोग्राम कैसे शुरू किए जाते हैं), सिस्टम आपके पीएटीएच में प्रत्येक निर्देशिका के माध्यम से जाकर फाइल की तलाश करता है। एक बार प्रोग्राम मिल जाने के बाद, भले ही यह कई निर्देशिकाओं में हो, खोज बाधित होती है और पहले पाया गया भाग चलता है।

फ़ाइल चलाने के लिए, आपको निष्पादन योग्य बिट को अनुमतियों में सेट करना होगा:

  • चूंकि आप पहले से ही कमांड लाइन पर हैं, आप बस टाइप कर सकते हैं chmod +x finename

  • या आप फ़ाइल को राइट क्लिक करके और गुण का चयन करके अनुमतियाँ सेट कर सकते हैं :

    वैकल्पिक शब्द

अब आप PATH में किसी भी निर्देशिका में फ़ाइल को कॉपी कर सकते हैं, यह देखने के लिए कि कौन-कौन से लोग वहां हैं - और वे प्रति उपयोगकर्ता आधार पर सेट हैं - टाइप echo $PATH

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

यदि आप एक निष्पादन योग्य फ़ाइल बनाते हैं cat, और इसे स्थानांतरित करते हैं /usr/local/sbin, तो इसे उचित के बजाय चलाया जाता है cat, जो अंदर रहता है /bin। आप पता लगा सकते हैं, जहां अपनी फ़ाइलें का उपयोग करके कर रहे हैं type catऔर whereis cat


2
ध्यान देने वाली एक बात: उनके सवाल से लगता है कि उन्होंने कुछ ऐसा संकलन और लिंक किया है gcc, जो स्वचालित रूप से निष्पादित बिट सेट करता है।
नाथन उस्मान

12

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

टर्मिनल में, जब भी आप किसी एप्लिकेशन का नाम लिखते हैं, तो कहते हैं gedit, टर्मिनल कुछ (पूर्व-निर्धारित) निर्देशिकाओं में दिखेगा, जिसमें एप्लिकेशन (एप्लिकेशनों के बायनेरिज़) होते हैं। इन निर्देशिकाओं के नाम एक चर में निहित हैं PATH। आप देख सकते हैं कि निष्पादन के द्वारा इस चर में क्या है echo $PATH। उन निर्देशिकाओं को अलग करके देखें :? उन निर्देशिकाओं कि टर्मिनल, खोज करता है, तो आप सिर्फ टाइप जाना होगा रहे हैं gedit, nautilusया a.out। जैसा कि आप देख सकते हैं, आपके a.outकार्यक्रम का मार्ग नहीं है। जब आप ऐसा करते हैं ./a.out, तो आप टर्मिनल को "वर्तमान निर्देशिका में देखो, और चलाओ a.out, और देखो मत जाओ " में बता रहे हैं PATH

समाधान 1

यदि आप ./हर बार टाइप नहीं करना चाहते हैं , तो आपको a.outनिर्देशिका में जोड़ना होगा $PATH। निम्नलिखित निर्देशों में, मैं मानूंगा कि रास्ता a.outहै /path/to/programs/, लेकिन आपको इसे अपने वास्तविक पथ में बदलना चाहिए।

  1. बस फ़ाइल के अंत में निम्नलिखित पंक्ति जोड़ें ~/.pam_environment:

    PATH DEFAULT=${PATH}:/path/to/programs

    स्रोत: लगातार पर्यावरण चर

  2. लॉग आउट करें और वापस लॉग इन करें। अब आप किसी भी निर्देशिका से a.outबिना चला सकेंगे ./

यदि आपके पास अन्य निर्देशिकाओं में अन्य कार्यक्रम हैं, तो आप उन्हें उपरोक्त पंक्ति में जोड़ सकते हैं। हालांकि, मैं उदाहरण के लिए "myPrograms" नामक एक निर्देशिका की सलाह दूंगा, और इसके तहत अपने सभी कार्यक्रम डालूंगा।

समाधान २

नोट:userName अपने वास्तविक Ubuntu उपयोगकर्ता नाम में परिवर्तन ।

क्या होगा यदि आपके पास अन्य कार्यक्रम हैं जिन्हें आप चलाना चाहते हैं? और वे सभी विभिन्न फ़ोल्डरों में हैं? खैर, एक "अधिक संगठित" समाधान एक फ़ोल्डर बनाने के लिए होगा जिसे binआपके होम डायरेक्टरी के तहत कहा जाता है , और उस फ़ोल्डर के तहत प्रतीकात्मक लिंक (शॉर्टकट) जोड़ें। ऐसे:

  1. mkdir /home/userName/bin

    • यह binआपके होम डायरेक्टरी के तहत फोल्डर बनाएगा ।
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • यह आपके a.outप्रोग्राम का "प्रतीकात्मक लिंक" (मूल रूप से, एक शॉर्टकट) बनाएगा bin
  3. लॉग आउट करें और वापस लॉग इन करें। अब आप किसी भी निर्देशिका से a.outबिना चला सकेंगे ./

अब, जब भी आपका कहीं और कोई कार्यक्रम हो, तो b.inअपने डेस्कटॉप पर प्रोग्राम को कहें , आपको बस इतना करना है: ln -s /home/userName/Desktop/b.in /home/userName/binऔर फिर आप इसे भी बिना चला सकेंगे ./

नोट: @ जो की टिप्पणी के लिए धन्यवाद , जब आप बैकअप करते हैं, तो प्रतीकात्मक लिंक को विशेष रूप से संभालना पड़ता है। डिफ़ॉल्ट रूप से, rsyncउन्हें बिल्कुल भी संसाधित नहीं करता है, इसलिए जब आप पुनर्स्थापित करते हैं, तो वे वहां नहीं होते हैं।


1
यह एक आसान ट्रिक है अगर इसे संयम से इस्तेमाल किया जाए। इसका उपयोग करने से आपका सिस्टम ऐसा काम करता है जिसकी किसी और को उम्मीद नहीं होगी। इसके अलावा, जब आप बैकअप करते हैं, तो सीमलिंक को विशेष रूप से संभालना पड़ता है। डिफ़ॉल्ट रूप से , rsync उन्हें बिल्कुल संसाधित नहीं करता है, इसलिए जब आप पुनर्स्थापित करते हैं तो वे वहां नहीं होते हैं।
जो

1

के रूप में जॉर्ज को अपने जवाब में बताया, यह आप ध्यान दें कि आपके मदद करता है कि क्रियान्वित वर्तमान कार्यशील निर्देशिका में एक फ़ाइल ( pwd)।

मुझे याद है कि यह प्रश्न बहुत समय पहले मेरे वरिष्ठ से पूछा गया था, उन्होंने कहा कि मुझे .अपने रास्ते से जुड़ना चाहिए ताकि जब मैं ऐसा करूं तो a.outवह वर्तमान निर्देशिका में दिखे और उस पर अमल करे। इस मामले में मुझे नहीं करना है ./a.out

लेकिन, व्यक्तिगत रूप से, मैं इसके खिलाफ सिफारिश करूंगा। यह मेरे साथ कभी नहीं हुआ, लेकिन यदि आप एक विदेशी नेटवर्क निर्देशिका या कुछ और, और एक दुर्भावनापूर्ण निष्पादन योग्य फ़ाइल पर lsमौजूद हैं, तो .आपके रास्ते में होना एक बहुत बुरा विचार है। ऐसा नहीं है कि आप इस समस्या में भाग लेंगे, बस कह रहे हैं।


ठीक है, स्टेफानो ने इस जानकारी को शामिल करने के लिए अपना जवाब अपनाया :)
श्रीकांत शरत

3
मैं पूरी तरह से जोड़ने के .लिए सहमत नहीं हूँ $PATH। बहुत खतरनाक विचार है।
नाथन उस्मान

1

अन्य उत्तरों के अलावा, यहां से वह आवश्यक हिस्सा man bashबताया गया है जो अच्छी तरह से समझाता है:

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

       यदि कमांड नाम में कोई स्लैश नहीं है, तो शेल पता लगाने का प्रयास करता है
       यह। यदि उस नाम से शेल फ़ंक्शन मौजूद है, तो वह फ़ंक्शन है
       FUNCTIONS में ऊपर वर्णित है। यदि नाम मेल नहीं खाता है
       फ़ंक्शन, शेल शेल बिल्डरों की सूची में इसके लिए खोज करता है। अगर
       एक मैच पाया जाता है, कि बिल्टइन मंगवाया गया है।

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

0

जब आप एक प्रोग्राम चलाते हैं, जो आपके लिए विशिष्ट है, जैसे आपका अपना। यह कार्यक्रम आपकी वर्तमान निर्देशिका में मौजूद होना चाहिए। A './' का कोई मतलब नहीं है जब आप एक मानक कमांड चलाते हैं जो $ PATH में कहीं है। एक कमांड "जो कमांड-टू-रन" आपको बताता है कि $ PATH में कमांड-टू-रन कहां है।


0
$ gcc hello.c -o /path/to/someplace/hello

कुछ स्थान पर एक निष्पादन योग्य उत्पादन करेगा। यदि वह स्थान आपके पथ पर है, तो आप फ़ाइल चला पाएंगे। आप इसे स्क्रिप्ट कर सकते हैं यदि आप कार्रवाई के लिए एक लेबल बनाना पसंद करते हैं "इस स्रोत कोड को gcc का उपयोग करके संकलित करें और अपने स्थान पर कुछ स्थान पर एक निष्पादन योग्य रखें"

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


0

./एक रास्ते के लिए अनावश्यक खोज को समाप्त करता है। ./केवल वर्तमान निर्देशिका में खोज करने के लिए बल। अगर हम नहीं देते ./तो यह विभिन्न पथ सिस्टम की तरह में सेट खोज करेंगे /usr/bin, /usr/sbin/आदि


0

"./" का अर्थ है कि आप वर्तमान निर्देशिका में एक फ़ाइल निष्पादित करना चाहते हैं, उदाहरण के लिए पूरे रास्ते को टाइप करने के लिए एक शॉर्टकट:

[root@server ~]#/path/to/file/file.pl

के रूप में ही है:

[root@server file]#./file.pl

पिछले उदाहरण में आप डायरेक्टरी और उसके सुपर-डायरेक्टरी से फाइल लोकेशन पर गए थे और फाइल को चालू डायरेक्टरी में चलाने के लिए "./" का उपयोग किया था।

इससे पहले कि यह " [रूट @ सर्वर ~] # / पथ / से / फ़ाइल / file.pl " भी फ़ाइल को निष्पादित करेगा यदि आप फ़ाइल स्थान पर अपना रास्ता "सीडी" के लिए आलसी करते हैं।


-4

यह बहुत सरल है और इसके कई उपयोग हैं।

  1. जब एक ही एप्लिकेशन के कई संस्करण इंस्टॉल किए जाते हैं, तो यह अलग-अलग पथ में उपलब्ध होगा लेकिन आपके बाइनरी में एक सॉफ्ट लिंक बनाया जा सकता है /usr/bin। उदाहरण के लिए, Python 2.7, Python 2.6 स्थापित है लेकिन / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6

यदि आप पथ में हैं /usr/local/binऔर पायथन को निष्पादित करते हैं तो यह हमेशा पायथन 2.7 को निष्पादित करेगा। निर्दिष्ट .करने से वर्तमान फ़ोल्डर निष्पादन योग्य हो जाएगा।

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