Pwd और / bin / pwd के बीच अजीब अंतर


15

मैंने वर्तमान निर्देशिका के साथ एक सिमलिंक जोड़ा ln -s . aa। यदि मैं निष्पादित करता हूं cd aa, और उसके बाद मैंने निष्पादित किया pwd, तो प्रतिक्रिया है /home/sim/aa

लेकिन अगर मैं /bin/pwdइसे प्रिंट करता हूं /home/sim(वर्तमान निर्देशिका नहीं बदली है)।

यह अंतर कहां से आता है?

जवाबों:


17

बैश सहित अधिकांश गोले में, pwdएक शेल बिलिन है:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

यदि आप उपयोग करते हैं /bin/pwd, तो आपको -Lबिल्टिन के समान परिणाम प्राप्त करने के लिए विकल्प का उपयोग करना चाहिए pwd:

$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test

डिफ़ॉल्ट रूप से, /bin/pwdसहानुभूति को अनदेखा करता है और वास्तविक निर्देशिका को प्रिंट करता है।

से info pwd:

`-L'
`--logical'
     If the contents of the environment variable `PWD' provide an
     absolute name of the current directory with no `.' or `..'
     components, but possibly with symbolic links, then output those
     contents.  Otherwise, fall back to default `-P' handling.

`-P'
`--physical'
     Print a fully resolved name for the current directory.  That is,
     all components of the printed name will be actual directory
     names--none will be symbolic links.

pwdडिफ़ॉल्ट रूप से बिल्ट-इन में सिम्लिंक शामिल है, सिवाय इसके कि -Pविकल्प का उपयोग किया जाता है, या -o physicalसेटइन सक्षम किया जाता है।

से man bash:

pwd [-LP]
              Print the absolute pathname of the  current  working  directory.
              The pathname printed contains no symbolic links if the -P option
              is supplied or the -o physical option to the set builtin command
              is  enabled.  If the -L option is used, the pathname printed may
              contain symbolic links.  The return status is 0 unless an  error
              occurs  while  reading  the  name of the current directory or an
              invalid option is supplied.

मुझे समझ में नहीं आ रहा है कि उन मतभेदों में कहां से आता है
user3581976

/bin/pwdडिफ़ॉल्ट रूप से सहानुभूति को अनदेखा करता है, info pwdमेरे उत्तर में भाग पढ़ें : वर्तमान निर्देशिका के लिए पूरी तरह से हल किए गए नाम को प्रिंट करें। यही है, मुद्रित नाम के सभी घटक वास्तविक निर्देशिका नाम होंगे - कोई भी प्रतीकात्मक लिंक नहीं होगा।
कोउन्ग्लम

@ user3581976: अधिक स्पष्ट रूप से मेरे अपडेट को देखें।
कोउन्ग्लम

Pwd के लिए -L कमांड क्यों है, हालांकि यह डिफ़ॉल्ट रूप से सेट है। और क्या pwd चलाने के लिए शेल / बिन / pwd कमांड का उपयोग नहीं करता है?
user3581976

2
@ user3581976: जिस छवि के साथ आप अपना शेल शुरू करते set -o physicalहैं, अब डिफ़ॉल्ट रूप pwdसे उपयोग का -Pविकल्प है, यदि आपके पास -Lविकल्प नहीं है , तो आप पथ को कैसे प्रिंट करते हैं जिसमें सिमलिंक शामिल है? यह https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlजानने के लिए पढ़ें कि क्या set -o physicalकरता है।
कोउन्ग्लम

7

एक प्रक्रिया के लिए यह संभव है कि इस सवाल का जवाब देने के लिए विषय पर होने के लिए थोड़ा जटिल है, एक विधि का उपयोग करके, इसकी वर्तमान कार्य निर्देशिका को निर्धारित करने के लिए फ़ाइल सिस्टम से पूछताछ की जाए। यही pwdप्रोग्राम और getcwdलाइब्रेरी फंक्शन करते हैं। यूनिक्स के शुरुआती दिनों में, वे यह पता लगाने के एकमात्र तरीके थे कि आपकी कार्यशील निर्देशिका क्या थी। यहां आपके प्रश्न के उत्तर का एक हिस्सा है जो मैं किसी भी अन्य उत्तर में, या यहां तक ​​कि इस साइट पर कहीं भी नहीं पा सकता (42 सेकंड के खोज के बाद):

  • जब शेल शुरू होता है, तो उसे इसकी वर्तमान कार्यशील निर्देशिका (शायद कॉल करके getcwd) मिलती है ।
  • इसके बाद, जब भी आप एक cd, pushdया popd, शेल स्ट्रिंग हेरफेर फ़ंक्शन का उपयोग करके कार्य निर्देशिका का ट्रैक रखते हैं। उदाहरण के लिए,

    • यदि आपकी कार्यशील निर्देशिका है /home/simऔर आप टाइप करते हैं cd .., तो शेल गणना करता है कि आपकी कार्यशील निर्देशिका क्या है /home
    • यदि आपकी कार्यशील निर्देशिका है /home/simऔर आप टाइप करते हैं cd ., तो शेल यह गणना करता है कि आपकी कार्यशील निर्देशिका अभी भी है /home/sim
    • यदि आपकी वर्किंग डायरेक्टरी है /home/simऔर आप टाइप करते हैं cd aa, तो शेल यह गणना करता है कि आपकी वर्किंग डायरेक्टरी है /home/sim/aa- बिना चेक किए कि क्या aaप्रतीकात्मक लिंक है।

    यह कॉलिंग की "लागत" को बचाने के लिए करता है getcwd। लेकिन यह एक व्यापार बंद है, क्योंकि इससे गलत जानकारी हो सकती है।

  • pwd(Builtin) कमांड बस खोल के याद / क्या काम कर रहा है निर्देशिका की गणना की धारणा को प्रदर्शित करता है।
  • इसके अलावा, शेल उपयोगकर्ता प्रक्रियाओं की सुविधा के लिए पीडब्ल्यूडी पर्यावरण चर में काम करने वाली निर्देशिका में अपनी याद / गणना की गई धारणा रखता है। एक प्रक्रिया को इस पर कभी भी भरोसा नहीं करना चाहिए अगर वह सटीक जानकारी चाहता है।

तो, लब्बोलुआब यह है कि खोल भ्रमित हो सकता है कि यह कहां है। लेकिन अगर आप टाइप करते हैं /bin/pwd, तो यह एक अलग प्रक्रिया में चलता है जिसमें शेल की धारणा तक पहुंच नहीं होती है जो कि कार्यशील निर्देशिका है, और इसलिए यह सही काम करने वाली निर्देशिका को, पुराने ढंग से निर्धारित करता है। (अपवाद: /bin/pwdकार्यक्रम पीडब्ल्यूडी पर्यावरण चर को देख सकता है , और जाहिर तौर पर यह तब होता है जब आप निर्दिष्ट करते हैं -L।) यहां एक और उदाहरण है कि शेल कैसे भ्रमित हो सकता है:

cd /home/sim/aa # मान लें कि /home, /home/simऔर /home/sim/aa
# सभी वास्तविक निर्देशिकाएं हैं (प्रतीकात्मक लिंक नहीं)।
pwd # आउटपुट: /home/sim/aaजो सही है।
mv ../aa ../bb
pwd # आउटपुट: /home/sim/aaजो गलत है।
/bin/pwd # आउटपुट: /home/sim/bbजो सही है।


और, यदि आप इस पर स्पष्ट नहीं हैं, तो यदि आप टाइप करते हैं ln -s . aaऔर cd aaफिर, आपकी वर्तमान कार्यशील निर्देशिका नहीं बदली है , तो इससे भी अधिक जब आप टाइप करते हैं, तो cd .- क्योंकि, यह अनिवार्य रूप से आप क्या कर रहे हैं जब आप टाइप करते हैं cd aa


धन्यवाद, बहुत अच्छा जवाब, यह वही है जो मैं इंतजार कर रहा था;)
user3581976

2
यह उत्तर थोड़ा झुका हुआ लगता है । लागत बचाने की-L तुलना में अधिक है - और उपयोगकर्ता-परिभाषित POSIX- निर्दिष्ट पर्यावरण चर है - उपयोगकर्ता-अंतरिक्ष अनुप्रयोगों को शायद इस पर भरोसा करना चाहिए (जो भी इसका मतलब है ...?) । वैसे भी, जब मैं सिम्बलिंक के सभी प्रशंसक नहीं हूं, तो यह उपयोगकर्ता के लिए कई पागल दिशाओं में अप्रत्यक्ष रूप से अप्रत्यक्ष है क्योंकि वह उनके साथ चुनना चाहिए - और यही कुछ के बारे में अधिक से अधिक है। $PWD -L
मिकसेर्व

1
यह स्वीकृत उत्तर होना चाहिए (प्रतीकात्मक लिंक प्रश्न का बिंदु नहीं हैं)।
थॉमस डिक्की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.