क्या फ़ाइल पर आउटपुट को रीडायरेक्ट करना फ़ाइल पर लॉक को लागू करता है?


30

अगर मेरे पास आज्ञा है

$ ./script >> file.log

दूसरी बार होने वाले पहले कॉल के समाप्त होने के साथ दो बार कॉल किया जाता है, तब क्या होता है?

क्या पहली कॉल को आउटपुट फ़ाइल पर एक विशेष लॉक मिलता है? यदि ऐसा है, तो लिखने का प्रयास करते समय दूसरी स्क्रिप्ट विफल हो जाती है, या शेल आउटपुट को स्वीकार करता है (स्क्रिप्ट को समाप्त करने की अनुमति देता है) और एक त्रुटि फेंक देता है?

या लॉग फाइल दो बार लिखी जाती है?


1
मुझे ऐसी किसी भी प्रणाली का पता नहीं है जो डिफ़ॉल्ट रूप से फ़ाइल को लॉक कर दे। अधिक संभावना यह है कि दोनों कार्यक्रम उनके लेखन को समाप्त कर देंगे, क्योंकि दोनों ही अपेंड मोड में होंगे। परिणाम अप्रत्याशित होंगे। "हैलो वर्ल्ड" के बजाय आप "hweolrllod" प्राप्त कर सकते हैं।
20

जवाबों:


18

चूंकि आप उपयोग कर रहे हैं >>, जिसका अर्थ है एपेंड, प्रत्येक इंस्टेंस से आउटपुट की प्रत्येक पंक्ति को उस क्रम में जोड़ा जाएगा, जो उस समय हुआ था।

अपनी स्क्रिप्ट उत्पादन प्रिंट हैं 1\nके माध्यम से 5\nप्रत्येक और उदाहरण दोनों के बीच एक एक सेकंड की देरी के साथ 2.5 सेकंड शुरू कर दिया है बाद में आप इस मिल जाएगा:

1
2
1
3
2
4
3
5
4
5

तो आपके प्रश्न का उत्तर देने के लिए: नहीं।


23

यूनिक्स सिस्टम द्वारा और बड़े अनिवार्य ताले से बचते हैं। ऐसे कुछ मामले हैं जहां कर्नेल उपयोगकर्ता प्रोग्राम द्वारा संशोधनों के खिलाफ एक फ़ाइल को लॉक कर देगा, लेकिन ऐसा नहीं है यदि यह केवल किसी अन्य प्रोग्राम द्वारा लिखा जा रहा है। कोई भी यूनिक्स सिस्टम किसी फाइल को लॉक नहीं करेगा क्योंकि एक प्रोग्राम इसे लिख रहा है।

यदि आप अपनी स्क्रिप्ट के समवर्ती उदाहरणों को एक-दूसरे के पैर की उंगलियों पर नहीं चलना चाहते हैं, तो आपको एक स्पष्ट लॉकिंग तंत्र का उपयोग करने की आवश्यकता है ।flock lockfile

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

अगर ऐसा हो सकता है तो बुरी बात यह है कि उदाहरणों में से एक आउटपुट के कई हिस्से लिखता है और उनसे एक साथ आने की उम्मीद करता है। एक उदाहरण से लिखने वालों के बीच, अन्य उदाहरण अपने स्वयं के लेखन का प्रदर्शन कर सकते हैं। उदाहरण के लिए, यदि उदाहरण 1 लिखता है foo, तो उदाहरण 2 लिखता है helloऔर केवल उदाहरण 2 लिखता है bar, तो फ़ाइल शामिल होगी foohellobar

एक प्रक्रिया प्रभावी ढंग से फाइल को लिखती है जब वह writeसिस्टम कॉल को कॉल करती है। एक कॉल writeपरमाणु है: प्रत्येक कॉल writeबाइट्स का एक क्रम लिखने के लिए जो अन्य कार्यक्रमों द्वारा बाधित नहीं होगी। writeप्रभावी रूप से लिखने के लिए किसी एकल कॉल को कितना डेटा देना है, इसकी एक सीमा होती है : बड़े आकारों के लिए, केवल डेटा की शुरुआत लिखी जाती है, और एप्लिकेशन को writeफिर से कॉल करना होगा । इसके अलावा, कई कार्यक्रम बफरिंग करते हैं: वे एक मेमोरी क्षेत्र में डेटा जमा करते हैं, फिर इस डेटा को एक चंक में लिखते हैं। कुछ प्रोग्राम एक पूरी लाइन या अन्य सार्थक पृथक्करण के बाद आउटपुट बफर को फ्लश करते हैं। ऐसे कार्यक्रमों के साथ, आप पूरी लाइनों को निर्बाध होने की उम्मीद कर सकते हैं, जब तक कि वे बहुत लंबे समय तक न हों (कुछ थियोबाइट्स तक; यह ओएस पर निर्भर करता है)। यदि प्रोग्राम सार्थक स्थानों पर नहीं बहता है, लेकिन केवल बफर आकार पर आधारित है, तो आप एक उदाहरण से 4kB की तरह कुछ देख सकते हैं, फिर दूसरे उदाहरण से 4kB, फिर पहली बार से 4kB और इसी तरह।

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