'>' के बारे में चेतावनी
यूनिक्स शुरुआती जिन्होंने अभी-अभी I / O पुनर्निर्देशन ( <
और >
) के बारे में सीखा है , जैसे अक्सर चीजों की कोशिश करते हैं
कमांड … input_file > the_same_file
या
कमांड ... < फ़ाइल > the_same_file
या, लगभग बराबर,
बिल्ली फ़ाइल | कमांड ...> the_same_file
( grep
, sed
, cut
, sort
, और spell
आज्ञाओं है कि लोगों को इस तरह के निर्माणों में उपयोग करने के लिए परीक्षा रहे हैं के उदाहरण हैं।) उपयोगकर्ता है कि इन स्थितियों फ़ाइल में परिणाम खाली होता जा रहा की खोज कर हैरान हैं।
एक अति सूक्ष्म अंतर जो अन्य उत्तर में उल्लिखित नहीं लगता है, उसे बैश (1) के पुनर्निर्देशन अनुभाग के पहले वाक्य में गुप्त पाया जा सकता है :
एक कमांड निष्पादित होने से पहले, इसके इनपुट और आउटपुट
को शेल द्वारा व्याख्या किए गए एक विशेष नोटेशन का उपयोग करके पुनर्निर्देशित किया जा सकता है ।
पहले पांच शब्दों को बोल्ड, इटैलिक, अंडरलाइन, बड़ा, ब्लिंकिंग, कलर्ड रेड और एक आइकन से चिह्नित किया जाना चाहिए , ताकि इस तथ्य पर जोर दिया जा सके कि शेल कमांड निष्पादित होने से पहले अनुरोध किए गए पुनर्निर्देशन (ओं)
को करता है । और याद भी
आउटपुट का पुनर्निर्देशन फ़ाइल का कारण बनता है… लेखन के लिए खोला जाना…। यदि फ़ाइल मौजूद नहीं है तो इसे बनाया जाता है; यदि यह मौजूद है तो इसे शून्य आकार में काट दिया जाता है।
तो, इस उदाहरण में:
sort roster > roster
शेल प्रोग्राम को चलाने roster
से पहले, इसे लिखने के लिए फ़ाइल को खोलता है , इसे रौंदता है (यानी, अपनी सभी सामग्री को छोड़ देता है) sort
। स्वाभाविक रूप से, डेटा को पुनर्प्राप्त करने के लिए कुछ भी नहीं किया जा सकता है।
कोई भोलेपन से उम्मीद कर सकता है कि
tr "[:upper:]" "[:lower:]" < poem > poem
बेहतर हो सकता है। क्योंकि शेल बाएं से दाएं पुनर्निर्देशन को संभालता है, यह poem
पढ़ने के लिए ( tr
मानक मानक के लिए ) खुलता है इससे पहले कि वह इसे लिखने के लिए (मानक आउटपुट के लिए) खोलता है। लेकिन यह मदद नहीं करता है। भले ही संचालन का यह क्रम दो फ़ाइल हैंडल देता है, लेकिन वे दोनों एक ही फ़ाइल को इंगित करते हैं। जब शेल पढ़ने के लिए फ़ाइल को खोलता है, तो सामग्री अभी भी वहां है, लेकिन वे अभी भी प्रोग्राम निष्पादित होने से पहले क्लोब किए जाते हैं।
तो, इसके बारे में क्या करना है?
समाधान में शामिल हैं:
जांचें कि क्या आप जो प्रोग्राम चला रहे हैं, उसकी अपनी आंतरिक, आंतरिक क्षमता है, यह निर्दिष्ट करने के लिए कि आउटपुट कहां जाता है। यह अक्सर एक -o
(या --output=
) टोकन द्वारा इंगित किया जाता है । विशेष रूप से,
sort roster -o roster
के बराबर है
sort roster > roster
को छोड़कर, पहले मामले में, sort
प्रोग्राम आउटपुट फ़ाइल खोलता है। और यह काफी स्मार्ट है कि आउटपुट फाइल को तब तक न खोलें, जब तक कि यह सभी इनपुट फाइल (ओं) को नहीं पढ़ लेता।
इसी प्रकार, कम से कम कुछ संस्करणों sed
एक है -i
(संपादन मैं n जगह) विकल्प है कि उत्पादन वापस इनपुट फ़ाइल के लिए बाहर लिखने के लिए इस्तेमाल किया जा सकता (फिर से, के बाद सभी इनपुट पढ़ा गया है)। जैसे संपादकों ed
/ ex
, emacs
, pico
, और vi
/ vim
उपयोगकर्ता एक पाठ फ़ाइल को संपादित करने और मूल फ़ाइल में संपादित टेक्स्ट को बचाने के लिए अनुमति देते हैं। ध्यान दें कि ed
(कम से कम) का उपयोग गैर-अंतःक्रियात्मक रूप से किया जा सकता है।
vi
एक संबंधित सुविधा है। यदि आप टाइप करते हैं , तो यह एडिट बफर की सामग्री को आउट टू आउट , आउटपुट को पढ़ने, और बफर में डालने (मूल सामग्री को बदलने) को लिख देगा ।:%!command
Entercommand
सामान्य लेकिन प्रभावी:
कमांड … input_file > temp_file && mv temp_file input_file
इसका दोष यह है कि, यदि input_file
कोई लिंक है, तो वह (संभवतः) एक अलग फ़ाइल द्वारा प्रतिस्थापित किया जाएगा। साथ ही, नई फ़ाइल आपके पास डिफ़ॉल्ट सुरक्षा के साथ होगी। विशेष रूप से, यह जोखिम वहन करता है कि फ़ाइल विश्व-पठनीय होगी, भले ही मूल input_file
न हो।
बदलाव:
command … input_file > temp_file && cp temp_file input_file && rm temp_file
जो अभी भी (संभावित) temp_file
दुनिया को पढ़ने योग्य छोड़ देगा । और भी बेहतर:
cp input_file temp_file && command … temp_file > input_file && rm temp_file
ये फ़ाइल की लिंक स्थिति, स्वामी और मोड (सुरक्षा) को संरक्षित करते हैं, संभवतः I / O की दोगुनी लागत पर। (आपको
विशेषताओं को संरक्षित करने के लिए इसे पसंद करने के लिए -a
या उस -p
पर एक विकल्प का उपयोग करने की आवश्यकता हो सकती है cp
।)
command … input_file > temp_file &&
cp --attributes-only --preserve=all input_file temp_file &&
mv temp_file input_file
(केवल पठनीयता के लिए अलग-अलग लाइनों में टूटा हुआ) यह फ़ाइल के मोड को संरक्षित करता है (और, यदि आप रूट, स्वामी हैं), लेकिन यह आपके द्वारा स्वामित्व में है (यदि आप रूट नहीं हैं), और इसे नया बनाता है ( अलग फाइल।
यह ब्लॉग
("इन-प्लेस" फाइलों का संपादन) सुझाव और व्याख्या करता है
{rm input_file && कमांड …> input_file ; } < input_file
इसके लिए आवश्यक है कि command
मानक इनपुट (लेकिन लगभग सभी फिल्टर कर सकते हैं) को संसाधित करने में सक्षम हो। ब्लॉग खुद को एक जोखिम भरा कीचड़ कहता है और इसके उपयोग को हतोत्साहित करता है। और यह आपके द्वारा और डिफ़ॉल्ट अनुमतियों के स्वामित्व वाली एक नई, अलग फ़ाइल (किसी भी चीज़ से लिंक नहीं) का निर्माण करेगा।
Moreutils पैकेज में एक कमांड होती है जिसे कहा जाता है sponge
:
कमांड ... input_file | स्पंज the_same_file
अधिक जानकारी के लिए यह उत्तर देखें ।
यहाँ कुछ ऐसा है जो मेरे लिए एक पूर्ण आश्चर्य के रूप में आया है:
वाक्यविन्यास कहता है :
[इन समाधानों में से अधिकांश] केवल पढ़ने के लिए फाइल सिस्टम है, जहां "रीड-ओनली" मतलब है कि आपके पर विफल हो जाएगा $HOME
होगा लिखने योग्य हो, लेकिन /tmp
हो जाएगा -केवल पढ़ने के लिए (डिफ़ॉल्ट रूप से)। उदाहरण के लिए, यदि आपके पास उबंटू है, और आपने रिकवरी कंसोल में बूट किया है, तो यह आमतौर पर मामला है। इसके अलावा, यहाँ-दस्तावेज़ ऑपरेटर <<<
भी वहाँ काम नहीं करेगा, क्योंकि इसे पढ़ने / लिखने की आवश्यकता /tmp
है
क्योंकि यह एक अस्थायी फ़ाइल को वहां भी लिख देगा।
(cf. इस प्रश्न में 'डी आउटपुट' शामिल है )
strace
निम्नलिखित उस मामले में काम कर सकता है:
तो, सवाल क्या था?
यह U & L पर एक लोकप्रिय विषय रहा है; इसे निम्नलिखित प्रश्नों में संबोधित किया गया है:
… और वह सुपर यूजर या उबंटू नहीं गिन रहा है। मैंने उपरोक्त प्रश्नों के उत्तर से लेकर इस उत्तर में बहुत सारी जानकारी शामिल की है, लेकिन सभी में नहीं। (यानी, अधिक जानकारी के लिए, ऊपर सूचीबद्ध प्रश्न और उनके उत्तर पढ़ें।)
PS मुझे उस ब्लॉग से कोई संबद्धता नहीं है जिसका मैंने उल्लेख किया है, ऊपर।