लिनक्स पर ">>" का उपयोग करते समय O_APPEND में फ़ाइलों को खोलें?


38

यदि हम उपयोग करते हैं echo 1234 >> some-fileतो प्रलेखन कहता है कि आउटपुट संलग्न है।

मेरा अनुमान है कि, यदि कुछ फ़ाइल मौजूद नहीं है, तो O_CREAT एक नई फ़ाइल बनाएगा। यदि >उपयोग किया गया था, तो O_TRUNC मौजूदा फ़ाइल को छोटा कर देगा।

के मामले में >>: क्या फ़ाइल को O_WRONLY (या O_RDWR) के रूप में खोला जाएगा और O_APPEND का अनुकरण करते हुए ऑपरेशन को समाप्त करने और लिखने की कोशिश की जाती है? या फ़ाइल O_APPEND के रूप में खोली जाएगी, यह सुनिश्चित करने के लिए कर्नेल को छोड़ कर कि क्या होता है?

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


12
एनएफएस पर समस्या यह नहीं है कि O_APPENDसमर्थित नहीं है; समस्या इसका अनुकरण है। एक स्थानीय फ़ाइल सिस्टम पर, एक ही फ़ाइल के साथ लिखने वाली कई प्रक्रियाएं O_APPEND कभी भी एक-दूसरे के डेटा को अधिलेखित नहीं करेंगी; एनएफएस पर, O_APPENDलिखने से पहले अंत की मांग करके अनुकरण किया जाता है, जो दौड़ की स्थिति की संभावना को छोड़ देता है। एनएफएस पर इसके आसपास कोई रास्ता नहीं है; प्रत्येक समानांतर लेखक को अपनी फ़ाइल लिखने की आवश्यकता होती है। इसके चारों ओर काम करने का एकमात्र तरीका एनएफएस सर्वर पर एक सर्वर प्रक्रिया सेटअप है, लॉग करने वालों को लॉग इन करना है |nc server port, और सर्वर में लॉग में आने वाले डेटा को जोड़ना है।
गुंतराम ब्लोह

@GuntramBlohm, +1, पुष्टि के लिए धन्यवाद। मूल रूप से, आपका सुझाव फ़ाइल में केवल एक लेखक प्रक्रिया का उपयोग करना है, और अन्य सभी लेखक प्रक्रियाएं इस प्रक्रिया से गुजरेंगी।
प्रेम

इतने अच्छे उत्तर, निश्चित नहीं कि मुझे कौन सा उत्तर स्वीकार करना चाहिए। पहले ब्रूस एडगर ने दिखाया कि O_APPEND का उपयोग किया जाता है। अगले random832 से पता चला कि यह मानकों में दिया गया है। अंत में, एरिक रेनॉफ ने उसी उत्तर के साथ स्रोत कोड दिखाया। सभी तीन दृष्टिकोण अंतिम पूर्ण चित्र में जोड़ते हैं।
प्रेम

6
संक्षेप में, एनएफएस बग का एक भार है और इसका उपयोग नहीं किया जाना चाहिए।
आर ..

2
हाँ, लेकिन हमने पहले ही उस तरीके को सीख लिया था जब O_EXCL का आविष्कार किया गया था।
केविन

जवाबों:


60

मैंने इसे चलाया: strace -o spork.out bash -c "echo 1234 >> some-file"आपके प्रश्न का पता लगाने के लिए। यह है जो मैंने पाया:

open("some-file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

"कुछ-फ़ाइल" नाम की कोई फ़ाइल उस निर्देशिका में मौजूद नहीं थी जिसमें मैंने echoकमांड चलाया था ।


50

यह केवल बाश में नहीं किया गया है, यह मानक द्वारा आवश्यक है।

एकल यूनिक्स विशिष्टता से :

लागू आउटपुट पुनर्निर्देशन फ़ाइल का नाम देगा जिसका नाम शब्द के विस्तार के परिणामस्वरूप नामित फ़ाइल विवरणक पर आउटपुट के लिए खोला जाएगा। फ़ाइल को इस तरह खोला जाता है जैसे कि POSIX.1-2008 के सिस्टम इंटरफेसेस वॉल्यूम में परिभाषित खुले () फ़ंक्शन को O_APPEND ध्वज के साथ बुलाया गया था। यदि फ़ाइल मौजूद नहीं है, तो इसे बनाया जाएगा।

कोई भी POSIX- अनुरूप शेल इसलिए इसे अवश्य करना चाहिए। कुछ यूनिक्स प्रणालियों पर, /bin/shएक गैर-पॉसिक्स बॉर्न शेल हो सकता है (बोर्न शेल मूल रूप से O_APPENDआविष्कार करने से पहले लिखा गया था), और उपलब्ध पॉसिक्स शेल आमतौर पर होगा ksh, जो shसोलारिस जैसे अलग पथ स्थान में उपलब्ध होगा /usr/xpg4/bin


2
दिलचस्प बात यह है कि ऐसा करने वाला एक शेल बॉर्न शेल नहीं है। बॉर्न शेल अंत तक O_TRUNC और lseek () के बिना खुलता है। ऐसा इसलिए होगा क्योंकि O_APPEND ध्वज को जोड़ने से पहले इसे लिखा गया था open()>>खुद को अपने पूर्ववर्ती थॉमसन शेल द्वारा पेश किया गया था।
स्टीफन चेज़लस

1
@ स्टीफेनचैलेजस इसके अलावा, मैंने विभिन्न संस्करणों के लिए सी शेल स्रोत को देखा, और O_APPEND ध्वज को 4.3BSD-Reno तक पेश नहीं किया गया।
रैंडम 832

यह कहता है "जैसा है", इसलिए इसे अलग तरीके से लागू नहीं किया जा सकता (लेकिन एक ही अवलोकन प्रभाव पैदा करना)? ऐसा लगता नहीं है कि मानक को O_APPEND के उपयोग की आवश्यकता है, बस कुछ ऐसा है जो "जैसा है" व्यवहार करता है।
थॉमस

1
@ थोमस इसका मतलब है कि आप O_APPEND के लिए प्रलेखित व्यवहार के सभी प्राप्त करने जा रहे हैं, जिसका अर्थ है कि हर लेखन के लिए अंत में repositioning। "जैसा कि अगर" केवल मानक क्रिया है जो कि उदाहरण के लिए अनुमति देने के लिए है, तो इसे गैर-पारंपरिक-यूनिक्स प्लेटफार्मों पर वास्तव में खुले () फ़ंक्शन को कॉल करने के अलावा कुछ अन्य तरीकों से खोला जा सकता है।
यादृच्छिक 832

+1, यह दिखाने के लिए कि यह व्यवहार मानकों में है।
प्रेम

32

स्रोत में देखते हुए, यह O_APPEND का उपयोग करता है। बैश 4.3.30 के लिए make_cmd.cलाइन 710-713 में पढ़ें:

case r_appending_to:                /* >>foo */
case r_append_err_and_out:          /* &>> filename */
  temp->flags = O_APPEND | O_WRONLY | O_CREAT;
  break;

स्रोत कोड परिप्रेक्ष्य से उत्तर दिखाने के लिए +1।
प्रेम

19

आइए देखें कि straceएक स्थानीय (गैर-एनएफएस) फाइल सिस्टम पर उपयोग करना:

$ strace -eopen -- bash -c "echo foo >> /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

$ strace -eopen -- bash -c "echo foo > /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3

अन्य गोले, अर्थात् dash, dash, shbusybox ने 'और mkshउसी तरह व्यवहार।

विकल्प का -e openअर्थ -e trace=openकेवल open()सिस्टम कॉल को ट्रेस करना है।

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