फ़ाइल में प्रोसेस प्रतिस्थापन का परिणाम / dev / fd / 63 क्यों होता है जो एक पाइप है?


40

मैं इस विशेष उदाहरण के संदर्भ में नामित पाइप को समझने की कोशिश कर रहा हूं।

मैं <(ls -l)अपने टर्मिनल में टाइप करता हूं और आउटपुट प्राप्त करता हूं bash: /dev/fd/63: Permission denied

यदि मैं टाइप करता हूं cat <(ls -l), तो मैं निर्देशिका सामग्री देख सकता हूं। यदि मैं इसके catसाथ प्रतिस्थापित करता echoहूं, तो मुझे लगता है कि मुझे टर्मिनल नाम (या यह है?) मिलता है।

echo <(ls -l)के रूप में उत्पादन देता है /dev/fd/63

इसके अलावा, यह उदाहरण आउटपुट मेरे लिए अस्पष्ट है।

ls -l <(echo "Whatever")
lr-x------ 1 root root 64 Sep 17 13:18 /dev/fd/63 -> pipe:[48078752]

हालाँकि, अगर मैं देता हूँ, ls -l <()यह मुझे निर्देशिका सामग्री सूचीबद्ध करता है।

नामित पाइप के मामले में क्या हो रहा है?

जवाबों:


37

जब आप करते हैं <(some_command), तो आपका शेल कोष्ठक के अंदर कमांड को निष्पादित करता है और पूरी चीज को एक फाइल डिस्क्रिप्टर से बदल देता है, जो कमांड के स्टडआउट से जुड़ा होता है। तो /dev/fd/63एक पाइप है जिसमें आपके ls कॉल का आउटपुट है।

जब आपको <(ls -l)कोई Permission deniedत्रुटि मिलती है , क्योंकि पूरी लाइन को पाइप से बदल दिया जाता है, प्रभावी /dev/fd/63रूप से कमांड के रूप में कॉल करने की कोशिश कर रहा है , जो निष्पादन योग्य नहीं है।

अपने दूसरे उदाहरण में, cat <(ls -l)बन जाता है cat /dev/fd/63। चूंकि बिल्ली आपको दी गई सामग्री के मापदंडों के रूप में दी गई फाइलों से पढ़ती है। echoदूसरी ओर बस अपने मापदंडों को "जैसा है"।

पिछले मामले तुम हो, <()बस, कुछ भी नहीं द्वारा बदल दिया क्योंकि इसमें कोई आदेश है। लेकिन यह गोले के बीच सुसंगत नहीं है, zsh में आपको अभी भी एक पाइप मिलता है (हालांकि खाली है)।

सारांश : <(command)आपको एक कमांड का उपयोग करने देता है, जहां आपको सामान्य रूप से एक फ़ाइल की आवश्यकता होगी।

संपादित करें: जैसा कि गिल्स बताते हैं, यह एक नामित पाइप नहीं है, बल्कि एक अनाम पाइप है। मुख्य अंतर यह है, कि यह केवल तब तक मौजूद रहता है, जब तक यह प्रक्रिया चल रही है, जबकि एक नामित पाइप (इसके साथ बनाया गया mkfifo) इसके साथ जुड़ी प्रक्रियाओं के बिना रहेगा।


5
mkfifoकेवल नामांकित पाइप बनाता है, बिना किसी सामग्री के। इसलिए आपको इसे स्वयं लिखने की आवश्यकता है (उदाहरण के लिए mkfifo mypipe; ls > mypipe)। और हाँ, पाइप को लिखता है जब तक कुछ प्रक्रिया पाइप से नहीं पढ़ता है तब तक ब्लॉक हो जाएगा।
crater2150

6
यहां कोई नामांकित पाइप नहीं है। /dev/fd/63एक अनाम पाइप है।
गिलेस एसओ- बुराई को रोकना '

1
@ crater2150, @Gilles / dev / fd / 63 वास्तव में एक नामित पाइप है। इसे कुछ इस तरह से देखें file <(ls)। शेल एक अनाम पाइप बनाता है, लेकिन फ़ाइल विवरणक एक नामित पाइप के रूप में दर्शाता है /dev/fd। यदि यह एक अनाम पाइप था, तो इसका कोई नाम नहीं होगा और इसे एक कमांड द्वारा नहीं खोला जा सकता है जिसे /dev/fd/63पारित किया गया है।
आर.वी.

2
@rv यह अभी भी एक अनाम पाइप है। तथ्य यह है कि एक फ़ाइल नाम है जो इस अनाम पाइप को संदर्भित करता है, इसे एक नामित पाइप नहीं बनाता है: एक नामित पाइप अलग है, यह एक फाइल सिस्टम पर कहीं मौजूद है, अनुमतियाँ और स्वामित्व है, आदि के /dev/fdप्रवेश किसी भी फ़ाइल को संदर्भित कर सकते हैं। डिस्क्रिप्टर, यहां तक ​​कि अनाम पाइप और सॉकेट, नेटवर्क सॉकेट, साझा मेमोरी सेगमेंट, आदि
गाइल्स का SO- बंद होना बुराई '

1
यह 63 क्यों है , हालांकि?
K3 --- rnc

-4

आप lsआदेश और पुनर्निर्देशन दोनों को गलत समझते हैं । lsकमांड लाइन पर दी गई फाइलों और निर्देशिकाओं को सूचीबद्ध करता है, मेरा मानना ​​है कि यह स्टड से किसी भी इनपुट को स्वीकार नहीं करता है। पुनर्निर्देशन > >>और <इनपुट देने और आउटपुट एकत्र करने के लिए फ़ाइल का उपयोग करने के तरीके हैं।


1
यहाँ एक फ़ाइल से पुनर्निर्देशन नहीं है। <(…)एक प्रक्रिया प्रतिस्थापन है।
गिलेस एसओ- बुराई को रोकना '

1
@IMSoP - जैसा कि गिल्स ने कहा - इसका नाम पाइप नहीं है - एक अनाम पाइप है। यह कुछ गोले में x|yसमान और लगभग समान है [num]<<REDIRECT। जहां यह भिन्न होता है वह fd लिंक का शेल का शाब्दिक प्रतिस्थापन है - /dev/fd/63और आदि और यह क्या करता है - या स्टडिन - स्टडिन। करो echo | readlink /dev/fd/0और अपने लिए देखो।
मोकेसर सेप 18'14

1
@IMSoP - यह एक devलिंक है - एक विशेष फ़ाइल। आप अधिकांश लिनक्स सिस्टम पर समान w / कोई भी फाइल डिस्क्रिप्टर कर सकते हैं - यहां तक ​​कि विशिष्ट |pipes, हालांकि मैं कहीं और व्यवहार के लिए वाउचर नहीं करता हूं। मुझे लगता है कि आप कहां से आ रहे हैं, लेकिन एक नामित पाइप अपने आप में एक अलग चीज है - यह एक इन-कर्नेल पाइप में एक फ़ाइल-सिस्टम संदर्भ है - एक नियमित फ़ाइल-सिस्टम संदर्भ, एक डिवाइस फ़ाइल नहीं।
15

1
@mikeserv दिलचस्प बात यह है कि बैश मैनुअल में उल्लेख है कि यह सिस्टम पर बिना /dev/fd/*नाम के पाइप बनाकर कहीं और काम करेगा । लेकिन मैं इस बात को लेता हूं कि /dev/fd/*एक नामांकित पाइप की तुलना में खुद एक अलग तंत्र है। संयोग से, विकिपीडिया का विवरण इस भेद की व्याख्या कर सकता है।
IMSoP

1
@mikeserv मुझे मिले अन्य संदर्भों के अनुसार, यह उस से भी सरल है: यदि /dev/fd/*उपलब्ध नहीं है, तो बैश एक नामित पाइप बना देगा /tmpऔर इसके बदले प्रक्रिया प्रतिस्थापन के लिए उपयोग करेगा। यह मेरे लिए बहुत अजीब नहीं लगता है, बस संभव के रूप में कई वातावरण में उपलब्ध कार्यक्षमता बना रही है।
IMSoP
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.