2009-12-13 4 views
7

यदि मैं उसी फ़ाइल में एक कमांड के आउटपुट को रीडायरेक्ट करता हूं तो यह पढ़ता है, इसकी सामग्री मिटा दी जाती है।यूनिक्स में एक खाली फ़ाइल में I/O पुनर्निर्देशन परिणामों के माध्यम से एक ही फ़ाइल को पढ़ने और लिखने का परिणाम क्यों?

sed 's/abd/def/g' a.txt > a.txt 

क्या कोई बता सकता है क्यों?

एसईडी मैं .bck के/अब्द/डीईएफ़/जी 'a.txt

संपादित करें:

उत्तर

16

पहली बात पुनर्निर्देशन करता है लिखने के लिए फ़ाइल खोलने के लिए है, थू किसी भी मौजूदा सामग्री को समाशोधन। sed फिर आप इस खाली फ़ाइल को पढ़ने की कोशिश करता है जिसे आपने अभी बनाया है, और कुछ भी नहीं करता है। फ़ाइल तब बंद हो जाती है, जिसमें कुछ भी नहीं होता है।

1

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

EDIT2: यह कुछ पाठक

पर OSX के लिए दिलचस्प हो सकता है, आप एक खाली विस्तार के साथ -i उपयोग करने के लिए एक बैकअप फ़ाइल के निर्माण को रोकने के लिए चाहते हैं, तो आप -e स्विच के रूप में अच्छी तरह से नहीं तो यह उपयोग करने की आवश्यकता सही ढंग से तर्क पार्स करने के लिए विफल रहता है:

एसईडी मैं -e के/abc/डीईएफ़/जी 'a.txt

+0

गलत, प्रश्न-प्रश्नकर्ता नोटों की कोशिश कि एक फ़ाइल से पढ़ने के लिए पारित किया गया है। दूसरे जवाब का सही कारण है। –

8

पुनर्निर्देशन संचालन <, >, आदि खोल द्वारा संभाले जाते हैं। जब आप खोल को कमांड देते हैं जिसमें पुनर्निर्देशन शामिल होता है, तो खोल पहले फ़ाइल खोल देगा। > के मामले में फ़ाइल लिखने के लिए खोला जाएगा, जिसका अर्थ है कि यह शून्य आकार में छोटा हो जाता है। पुनर्निर्देशन फ़ाइलों को खोले जाने के बाद, खोल एक नई प्रक्रिया शुरू करता है, किसी भी संभावित पुनर्निर्देशित फ़ाइलों को अपने मानक इनपुट, आउटपुट और त्रुटि को बाध्य करता है, और उसके बाद केवल आपके द्वारा दिए गए आदेश को निष्पादित करता है। तो जब आपके उदाहरण में sed कमांड निष्पादन शुरू होता है, तो a.txt को पहले ही खोल से छोटा कर दिया गया है।

संयोग से, और कुछ हद तक स्पर्शिक रूप से, यह कारण है कि आप सीधे sudo के साथ पुनर्निर्देशन का उपयोग नहीं कर सकते हैं क्योंकि यह वह खोल है जिसे पुनर्निर्देशन फ़ाइल खोलने की अनुमति की आवश्यकता होती है, आदेश को निष्पादित नहीं किया जाता है।

0

stdout और stderr पहले तैयार किए जाएंगे और फिर stdin और फिर कमांड निष्पादित करेंगे। तो a.txt पहले stdout के लिए स्पष्ट होगा और फिर जब comamnd निष्पादित कोई सामग्री नहीं मिल सका। एसईडी मैं के/अब्द/डीईएफ़/जी 'a.txt या sed' s/अब्द/डीईएफ़/जी 'a.txt 1 <> a.txt