क्या पाथ खोज में सिम्बलिंक्स शामिल हैं?


9

इस साइट पर POSIX शेल मानक कहता है

http://pubs.opengroup.org/onlinepubs/9699919799/

PATHनिष्पादनयोग्य को देखने के लिए गोले का उपयोग कैसे किया जाता है:

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

खैर, ऐसा नहीं है कि यह वास्तविक POSIX कार्यान्वयन में कैसे काम करता है:

man which कहते हैं:

"फ़ाइलों के लिंक (या लिंक) जो वर्तमान परिवेश में निष्पादित किए जाएंगे, के पास इसके तर्क दिए गए थे, इसके तर्क एक कड़ाई से POSIX-अनुरूप शेल में कमांड के रूप में दिए गए थे। यह ऐसा करता है कि निष्पादन योग्य फ़ाइलों के लिए PATH को खोजकर उसके नाम से मेल खाता है। तर्क। यह प्रतीकात्मक लिंक का पालन नहीं करता है। "

ठीक है, आइए इस स्थिति को देखें:

$ pwd /home/mark

$ echo $PATH /home/mark/bin:...

$ ls -l bin/foobar
lrwxrwxrwx 1 mark mark 18 Dec 12 22:51 bin/foobar -> /home/mark/foobar1
$ touch foobar1
$ which foobar
$ chmod a+x foobar1
$ which foobar
/home/mark/bin/foobar

ठीक है, यहां PATHसही नाम के साथ एक प्रतीकात्मक लिंक है , और इसे lsनिष्पादन योग्य होने की सूचना दी गई है।

which यह बिल्कुल नहीं दिखता है, लेकिन केवल इस बात में दिलचस्पी है कि यह किस ओर इशारा करता है।

इस तथ्य के बावजूद कि दोनों man whichस्पष्ट रूप से कहते हैं कि यह प्रतीकात्मक लिंक का पालन नहीं करता है (और वास्तव में हम इसे नहीं देखते हैं, क्योंकि which foobarयह प्रिंट नहीं करता है foobar1), और यह भी कि ऊपर उद्धृत पोज़िक शेल प्रलेखन, कभी भी PATHएल्गोरिथम में सिमिलिंक का पालन करने का उल्लेख नहीं करता है।

तो, क्या whichऔर मौजूदा गोले गलत हैं, या मैं प्रलेखन को नहीं समझ रहा हूं?

स्पष्ट करने के लिए:

मैं जानता हूं और मौजूदा व्यवहार की व्याख्या कर सकता हूं। मेरा सवाल "यह कैसे काम करता है?" नहीं है। वह हम जानते है।

मेरा प्रश्न दस्तावेज़ीकरण के बारे में है: जहाँ मैंने उद्धृत किए गए दस्तावेज़ का पालन करने में मेरी गलती कहाँ है। या डॉक्यूमेंटेशन गलत है?

प्रेरणा: मुझे परवाह क्यों है?

खैर, मैं एक कार्यान्वयनकर्ता हूं। विभिन्न कार्यान्वयनकर्ताओं की अलग-अलग आवश्यकताएं होती हैं। मेरे लिए, आवश्यकता इस बात की है कि वर्तमान POSIX मानक MUST के शब्द का अनुसरण किया जाना चाहिए (या, अधिक सटीक रूप से, सबसे अच्छा यह हो सकता है, क्योंकि, मानक स्वयं कुछ छोटी गाड़ी है)। जैसे यह भगवान का शब्द था।

अब, मानक शब्दांकन बहुत स्पष्ट है - निम्नलिखित सिम्बलिंक का उल्लेख नहीं किया गया है, जहां कई अन्य स्थानों पर, यह उल्लेख किया गया है कि इसे कहाँ किया जाना चाहिए। तो इस मामले में, नहीं।

हालाँकि, मैं हमेशा जाँच करता हूँ कि कैसे dashऔर कैसे bashव्यवहार करें, बस सुनिश्चित करने के लिए। अब निश्चित रूप से, यहाँ थोड़ी समस्या है, dashभले ही इसे POSIX के रूप में बिल किया गया हो, POSIX के अनुरूप बहुत से छोटे कीड़े हैं। bash, मुझे अभी तक POSIX के साथ किसी भी कीड़े को ढूंढना है, लेकिन ... bash वास्तव में POSIX नहीं है, यह उससे कहीं अधिक है।

इसलिए यह अब आपके पास है। यही कारण है कि मुझे परवाह है।


आप समझ में नहीं आता: जिस पर सिमलिंक का पालन नहीं करता फ़ाइलें$PATHसहानुभूति हो सकती है। कोशिश करो which sh
इपोर सिरकार

ठीक है, लेकिन मेरे मामले $PATHमें कोई सहानुभूति नहीं है।
user322908

लगभग सभी स्थितियों में, सहानुभूति का पारदर्शी रूप से पालन किया जाता है। जिन मामलों में वे आमतौर पर स्पष्ट रूप से उल्लिखित नहीं होते हैं (उदाहरण के लिए सिस्टम कॉल जैसे lstat(2)), उनका अनुसरण करना आमतौर पर नहीं कहा जाता है। उदाहरण के लिए, open(2)केवल व्यवहार के बारे में बात करते समय सहानुभूति का वर्णन है O_CREAT | O_EXCL। यह बताने की आवश्यकता नहीं है कि लक्ष्य फ़ाइल खोली जाएगी।
बरमार

जवाबों:


10

सिम्लिंक की अनुमतियाँ स्वयं अप्रासंगिक हैं। अगर आपने कोशिश की तो आप उन्हें बदल भी नहीं सकते।

क्या चीजें अंतर्निहित फ़ाइल की अनुमति हैं।

आपके पैट में निर्देशिकाओं का होना ठीक है, जिसमें निष्पादन योग्य लोगों के प्रति सहानुभूति शामिल है। वास्तव में, यह संभावना है कि आपके PATH में कई निष्पादक सहानुभूति हैं। उदाहरण के लिए, डेबियन / ubuntu जैसी प्रणालियों पर:

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 23  2017 /bin/sh -> dash

प्रलेखन

से man chmod:

chmod प्रतीकात्मक लिंक की अनुमति कभी नहीं बदलता है; chmod सिस्टम कॉल उनकी अनुमति नहीं बदल सकता है। यह एक समस्या नहीं है क्योंकि प्रतीकात्मक लिंक की अनुमति कभी भी उपयोग नहीं की जाती है। हालाँकि, कमांड लाइन पर सूचीबद्ध प्रत्येक प्रतीकात्मक लिंक के लिए, chmod पॉइंट-टू-फ़ाइल की अनुमतियों को बदलता है। इसके विपरीत, chmod आवर्ती निर्देशिका ट्रैवर्सल्स के दौरान प्रतीकात्मक लिंक की उपेक्षा करता है। [महत्व दिया।]

उदाहरण

शेल में एक परीक्षण है, -xयह निर्धारित करने के लिए कि क्या कोई फ़ाइल निष्पादन योग्य है। आइए कोशिश करते हैं कि:

$ ls -l
total 0
lrwxrwxrwx 1 john1024 john1024 7 Dec 12 23:36 foo -> foobar1
-rw-rw---- 1 john1024 john1024 0 Dec 12 23:36 foobar1
$ [ -x foo ] && echo foo is executable
$ chmod +x foobar1
$ [ -x foo ] && echo foo is executable
foo is executable

इसलिए, जैसे आपने पाया which, शेल तब तक सॉफ्टलिंक निष्पादन योग्य नहीं मानता जब तक कि अंतर्निहित फ़ाइल निष्पादन योग्य नहीं होती।

कैसे काम करता है

डेबियन सिस्टम पर, whichएक शेल स्क्रिप्ट है। कोड का प्रासंगिक अनुभाग है:

 case $PROGRAM in
  */*)
   if [ -f "$PROGRAM" ] && [ -x "$PROGRAM" ]; then
    puts "$PROGRAM"
    RET=0
   fi
   ;;
  *)
   for ELEMENT in $PATH; do
    if [ -z "$ELEMENT" ]; then
     ELEMENT=.
    fi
    if [ -f "$ELEMENT/$PROGRAM" ] && [ -x "$ELEMENT/$PROGRAM" ]; then
     puts "$ELEMENT/$PROGRAM"
     RET=0
     [ "$ALLMATCHES" -eq 1 ] || break
    fi
   done
   ;;
 esac

जैसा कि आप देख सकते हैं, यह -xनिर्धारित करने के लिए परीक्षण का उपयोग करता है कि एक फ़ाइल निष्पादन योग्य है।

POSIX -xइस प्रकार परीक्षण को निर्दिष्ट करता है:

-x pathname
सही है यदि pathname किसी फ़ाइल के लिए मौजूदा निर्देशिका प्रविष्टि का समाधान करता है, जिसके लिए फ़ाइल को निष्पादित करने की अनुमति है (या इसे खोजें, यदि यह एक निर्देशिका है), तो फ़ाइल रीड, राइट और निर्माण में परिभाषित किया जाएगा। यदि मार्गनाम हल नहीं किया जा सकता है तो गलत है, या यदि पथनाम फ़ाइल के लिए मौजूदा निर्देशिका प्रविष्टि का समाधान करता है, जिसके लिए फ़ाइल को निष्पादित (या खोज) करने की अनुमति नहीं दी जाएगी। [महत्व दिया।]

इसलिए, POSIX यह जांचता है कि पथनाम किसके लिए हल होता है। दूसरे शब्दों में, यह सहजीवन को स्वीकार करता है।

POSIX कार्य निष्पादित करता है

POSIX कार्यकारी समारोह सिमलिंक इस प्रकार है। POSIX कल्पना त्रुटि की शर्तों को निर्दिष्ट करने के लिए लंबाई पर चलती है जो रिपोर्ट कर सकती है कि क्या सहानुभूति गोलाकार या बहुत गहरी है, जैसे:

[ELOOP]
पथ या फ़ाइल तर्क के समाधान के दौरान सामने आए प्रतीकात्मक लिंक में एक लूप मौजूद है।

[ELOOP]
{SYMLOOP_MAX} से अधिक पथ या फ़ाइल तर्क के समाधान के दौरान प्रतीकात्मक लिंक का सामना करना पड़ा।
[ENAMETOOLONG]
पथ तर्क के समाधान में एक प्रतीकात्मक लिंक का सामना करने के परिणामस्वरूप, प्रतिस्थापित पथनाम स्ट्रिंग की लंबाई {PATH_MAX} से अधिक हो गई।


मैंने आपके उत्तर में जो कुछ भी लिखा है, मैं जानता हूं। मुझे पता है कि चीजें "काम" कैसे करती हैं। यह मेरा सवाल नहीं है। मेरा प्रश्न प्रलेखन के बारे में है। मुझे इंगित करें कि मैं प्रलेखन कहां नहीं समझ रहा हूं। या मुझे बताओ कि प्रलेखन गलत है।
user322908

@ user322908 अधिकांश प्रणालियों पर, whichएक शेल स्क्रिप्ट है। इस प्रकार, यह संभावना है -xकि मैंने जो परीक्षण दिखाया , उसका उपयोग कर रहा हूं। POSIX के अनुसार, -xपरीक्षण करता है कि क्या कोई फ़ाइल निष्पादन योग्य के लिए "हल" होती है। अगर आप कुछ अलग देख रहे हैं, तो आप कहां देख रहे हैं?
जॉन 1024

धन्यवाद और मुझे इस तरह के दर्द के लिए खेद है ... मुझे एहसास है कि मेरा प्रश्न 99% से अधिक प्रश्नों से अलग है, इसलिए यह समझना मुश्किल है कि मैं आखिर क्या हूं। फिर, मुझे "कैसे" whichकाम करने में कोई दिलचस्पी नहीं है , या यह है -xया कुछ और है। मुझे यह जानने में दिलचस्पी है कि मैं जिस दस्तावेज़ का हवाला देता हूं, उसका सही ढंग से पालन नहीं कर रहा हूं।
user322908

4
@ user322908 POSIX execफ़ंक्शन सिमिलिंक का अनुसरण करता है। ऐसा लगता है कि बहुत स्पष्ट है कि सहानुभूति फ़ाइलें POSIX के तहत निष्पादन योग्य हो सकती हैं।
जॉन 1024

2
मैंने उबंटू को 17.10 पर man which भी चेक किया जो कहता है कि "यह पथ के नामों को स्पष्ट नहीं करता है।" इसका मतलब यह नहीं है कि यह लिंक का पालन नहीं करता है। इसका मतलब केवल यह है, जैसा कि आपने देखा, कि यह नामों को "कैनोनिकलाइज़" नहीं करता है।
जॉन 1024

3

इस मामले में अंतिम मार्ग को स्पष्ट किए बिना सहानुभूति का पालन पारदर्शी तरीके से किया जाता है। दूसरे शब्दों में, whichइस बात की परवाह नहीं करता है कि /home/mark/binकोई सिमलिंक है या नहीं। क्या यह परवाह करता है कि फ़ाइल /home/mark/bin/foobarमौजूद है या नहीं। इसे पथ के साथ मैन्युअल रूप से समतल करने की आवश्यकता नहीं है - ओएस अपने आप ही ठीक कर सकता है।

और वास्तव में, जब whichफ़ाइल की जानकारी के बारे में पूछा जाता है /home/mark/bin/foobar, तो ओएस नोटिस /home/mark/binएक सिमलिंक है, इसका अनुसरण करता है, और सफलतापूर्वक foobarलक्ष्य निर्देशिका में पाता है।

यह डिफ़ॉल्ट व्यवहार है जब तक कि प्रोग्राम फ़ाइल का उपयोग open(…, O_NOFOLLOW)या उपयोग नहीं करता है fstatat(…, AT_SYMLINK_NOFOLLOW)

[टिप्पणियों में विलय]

जब आप कहते हैं कि शेल यूटिलिटीज केस-बाय-केस के आधार पर करते हैं, तो यह कर्नेल सिस्कल्स के साथ समान नहीं है: सभी फाइल-संबंधित कॉल डिफ़ॉल्ट रूप से सीलिंक्स का पालन करते हैं , जब तक कि "nofollow" ध्वज नहीं दिया जाता है। (यहां तक ​​कि लेस्टैट पिछले एक को छोड़कर सभी पथ घटकों में सीमलिंक का अनुसरण करता है।)

जब विनिर्देश स्पष्ट रूप से उल्लेख नहीं करता है कि सिमलिंक के साथ क्या करना है, तो इसका मतलब है कि डिफ़ॉल्ट व्यवहार का उपयोग किया जाएगा। यही है, पथ एल्गोरिथ्म निथर्स के बाद एक शेल मैन्युअल रूप से सीमिंक्स को हल करता है और न ही यह स्पष्ट रूप से ओएस से बाहर निकलता है। (यह केवल निष्पादन योग्य नाम के साथ प्रत्येक $ PATH घटक को समाप्‍त करता है।)

जब (1) मैनुअल पेज कहता है कि यह सिम्लिंक का पालन नहीं करता है, तो इसका मतलब कई चीजें हो सकती हैं, लेकिन जीएनयू कोरुटिल्स संस्करण इसे इस तरह बताता है:

जब दो समान निर्देशिकाओं को अलग माना जाएगा, जब उनमें से एक में एक प्रतीकात्मक लिंक के साथ एक पथ होगा।

यह बहुत कम दायरे में है - इसका मतलब केवल डुप्लिकेट से बाहर निकलने के लिए सभी रास्तों whichको मैन्युअल रूप से रद्द करने का प्रयास नहीं होगा , लेकिन इसका मतलब यह नहीं है कि यह टूल सामान्य रूप से ओएस द्वारा अनुसरण किए जाने वाले सिम्लिंक से बाहर निकल जाएगा। उदाहरण के लिए, यदि /binकोई सिमलिंक है /usr/bin, तो रनिंग दोनों और which -a shवापस आ जाएगी । /bin/sh/usr/bin/sh


हाँ धन्यवाद, मुझे यह सब पता है। मेरा सवाल यह नहीं है कि चीजें "काम" कैसे करती हैं। मुझे पता है कि वे कैसे काम करते हैं। वह मेरी बात नहीं है। मेरी बात प्रलेखन के बारे में है। मैं गलत तरीके से प्रलेखन का पालन कर रहा हूं। या डॉक्यूमेंटेशन गलत है।
user322908

2
आप दस्तावेज़ को गलत तरीके से समझ रहे हैं - अगर यह सिम्बलिंक का उल्लेख नहीं करता है, तो इसका मतलब है कि यह मैन्युअल रूप से सिम्बलिंक्स को हल नहीं करता है , लेकिन नियमित ओएस व्यवहार अभी भी लागू होता है। जीएनयू whichमैनुअल पेज इसे अलग तरह से बताता है: "जो दो समकक्ष निर्देशिकाओं को अलग-अलग मानेंगे जब उनमें से किसी के पास एक प्रतीकात्मक लिंक के साथ एक पथ होगा।"
user1686

ठीक है, वह बेहतर है धन्यवाद! मैं समझने की कोशिश कर रहा हूं ... लेकिन ... मेरे गले में दर्द होने पर क्षमा करें: "नियमित रूप से ओएस व्यवहार" सदैव सहानुभूति का पालन करने के लिए नहीं है। उपयोगिताओं के बहुत सारे हैं कि नहीं। यह मामला-दर-मामला आधार पर है।
user322908

1
सभी कर्नेल कॉल - chdir, open, chmod, निष्पादित करें ... - जब तक आप AT_SYMLINK_NOFOLLOW या समान निर्दिष्ट नहीं करते हैं , तब तक पथ और पूंछ दोनों में सीमलिंक का पालन किया जाएगा । (lstat केवल एक ही है जो पूंछ पर सहानुभूति नहीं करता है, लेकिन फिर भी शेष पथ के लिए ऐसा करता है।) इसलिए डिफ़ॉल्ट व्यवहार को सहानुभूति का पालन करना है। उदाहरण के लिए, जब कोई शेल कॉल execve("/home/mark/bin/foobar", …)करता है , तो इसके परिणामस्वरूप सभी सिम्बलिंक्स का पालन किया जाएगा।
user1686

ठीक है मुझे लगता है कि मैं execveतर्क खरीद रहा हूं , वास्तव में, मेरे कार्यान्वयन में यह एक execl()ही बात है। यदि आप इसे अपने उत्तर में शामिल करते हैं तो कृपया मुझे स्वीकार होगा।
user322908

1

शेल अपने दस्तावेज़ीकरण के अनुरूप है कि वह pathname रिज़ॉल्यूशन के नियमों का पालन करता है। whichइसके प्रलेखन के अनुरूप है। दोनों थोड़ा अलग काम करते हैं।

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

जब एक कमांड निष्पादित किया जाता है, लिंक धारा 4.13 पथ नाम संकल्प के अनुसार "बाद" है उसी में । किसी फ़ाइल को निष्पादित करने के लिए प्रासंगिक खंड है:

अन्य सभी मामलों में, सिस्टम शेष पथनाम को उपसर्ग करेगा, यदि कोई हो, प्रतीकात्मक लिंक की सामग्री के साथ, सिवाय इसके कि यदि प्रतीकात्मक लिंक की सामग्री खाली स्ट्रिंग है, तो या तो पथनाम संकल्प फंक्शन रिपोर्टिंग के साथ विफल हो जाएगा [ENOENT] ] एक समतुल्य नैदानिक ​​संदेश लिखने में त्रुटि और उपयोगिताओं, या प्रतीकात्मक लिंक वाली निर्देशिका के पथनाम का उपयोग प्रतीकात्मक लिंक की सामग्री के स्थान पर किया जाएगा। यदि प्रतीकात्मक लिंक की सामग्री में केवल वर्ण शामिल हैं, तो शेष पथनाम के सभी प्रमुख वर्ण परिणामी संयुक्त मार्गनाम से छोड़े जाएंगे, जिससे केवल प्रतीकात्मक लिंक सामग्री से प्रमुख वर्ण होंगे। उन मामलों में जहां उपसर्ग होता है, यदि संयुक्त लंबाई {PATH_MAX} से अधिक है, और कार्यान्वयन इसे त्रुटि मानता है, पथनाम रिज़ॉल्यूशन [ENAMETOOLONG] त्रुटि और उपयोगिताओं के साथ एक समतुल्य नैदानिक ​​संदेश लिखने वाले कार्यों में विफल हो जाएगा। अन्यथा, हल किया गया पथनाम केवल बनाए गए पथनाम का संकल्प होगा। यदि परिणामस्वरूप पथनाम एक के साथ शुरू नहीं होता है, तो पथनाम के पहले फ़ाइल नाम के पूर्ववर्ती को प्रतीकात्मक लिंक वाली निर्देशिका होने के लिए लिया जाता है।

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