& 6 और / देव / fd / 6 में क्या अंतर है?


11

फाइल डिस्क्रिप्टर 6 से पढ़ने के लिए मैं ( <&6या </dev/fd/6उर्फ /proc/self/fd/6) का उपयोग कर सकता हूं । आमतौर पर दोनों समान रूप से अच्छी तरह से काम करते हैं। हालाँकि अगर वह फाइल डिस्क्रिप्टर सॉकेट होता है, तो अजीब चीजें होती हैं। उदाहरण के लिए:

$ bash -c 'ls -l /dev/fd/6;cat /dev/fd/6' 6</dev/tcp/localhost/12345
lrwx------ 1 michas michas 64 Jan 10 19:50 /dev/fd/6 -> socket:[315010]
cat: /dev/fd/6: No such device or address

यहाँ lsपता चलता है कि वर्णनकर्ता वास्तव में मौजूद है। लेकिन इस तरह से डेटा तक पहुंच संभव नहीं है। अगर मैं cat <&6इसके बजाय सब कुछ फिर से अच्छी तरह से काम करता हूं ।

फ़ाइल डिस्क्रिप्टर तक पहुँचने के दोनों तरीकों में क्या अंतर है?

क्या एक डिस्क्रिप्टर तक पहुंचने का एक अच्छा तरीका है यदि संख्या एक चर में दी गई है? ( </dev/fd/$fdकाम करेगा, लेकिन <&$fdनहीं।)

(उपर्युक्त स्थिति को लिनक्स पर देखा जा सकता है, लेकिन ओपनबीएसडी पर नहीं। - ऐसा लगता है कि फ़ाइल विवरणक एक नियमित वर्ण उपकरण है।)


1
क्या यह डुप्लीकेट एक unix.stackexchange.com/q/98958/38906 है
cuonglm

2
धन्यवाद। यह संबंधित है लेकिन वास्तव में डुप्लिकेट नहीं है।
10

जवाबों:


5

ऐसा इसलिए है क्योंकि /dev/fd/प्रविष्टियों से पढ़ना जो सॉकेट का प्रतिनिधित्व करता है लिनक्स पर लागू नहीं होता है। आप यहाँ तर्क करने पर काफी अच्छा लिख ​​सकते हैं। तो आप statलिंक पर कॉल कर सकते हैं , और इसीलिए आप इसे देखते हैं ls, लेकिन पहुंच जानबूझकर अस्वीकृत है।

अब दूसरे भाग के लिए - bash -c 'ls -l /dev/fd/6; cat <&6' 6</dev/tcp/localhost/12345काम क्यों करता है ? ऐसा इसलिए है क्योंकि सॉकेट को सॉकेट / फ़ाइल एपीआई का उपयोग करके पढ़ा जाता है, न कि /procफाइलसिस्टम। यह वही है जो मैंने देखा है:

  1. bash उदाहरण आपके टर्मिनल में चल रहा है fd 6 के साथ सॉकेट बनाता है।
  2. चाइल्ड bashरन और कॉल dup2(6, 0), आपके सॉकेट को cat'एस' के रूप में संलग्न करने के लिए stdin
  3. यदि dup2कॉल विफल नहीं हुआ, तो बिल्ली से पढ़ता है stdin

आप इसे पुन: पेश कर सकते हैं और इसके साथ देख सकते हैं:

netcat -lp 12345    # in another terminal session (GNU netcat)
strace -f -e trace=open,read,write,dup2 bash -c 'ls -l /dev/fd/6; cat <&6' \
 6</dev/tcp/localhost/12345

यदि आप सोच रहे हैं कि bashबच्चे की प्रक्रिया में एफडी 6 तक पहुंच क्यों है - फाइल डिस्क्रिप्टर जीवित रहते हैं fork, और यदि उन्हें बंद करने के लिए चिह्नित नहीं किया जाता है exec, तो वे वहां भी बंद नहीं होते हैं।


3

आपके प्रत्यक्ष प्रश्न का उत्तर देने के लिए, " अंतर क्या है ?":

जब आप पुनर्निर्देशित करते हैं <&6, तो शेल dup2()फाइल डिस्क्रिप्टर को डुप्लिकेट करने के लिए एक सिस्टम कॉल का उपयोग करता है । जब आप (से) को पुनर्निर्देशित करने का प्रयास </dev/fd/6करेंगे, तो यह उपयोग करेगा open()

कर्नेल open()सॉकेट में समर्थन नहीं करता है /dev/fd; वे केवल सजावट की जानकारी के लिए निर्देशिका में मौजूद हैं ।

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