2012-03-08 19 views
6

मेरे पास एक बाहरी प्रक्रिया है जो फ़ाइल को लिखना शुरू करती है।
मैं स्क्रिप्ट कैसे लिखूं जो फ़ाइल बंद होने तक प्रतीक्षा करता है (जब दूसरी प्रक्रिया लेखन के साथ की जाती है)।फ़ाइल बंद होने तक प्रतीक्षा कैसे करें

उत्तर

3

इस लक्ष्य को हासिल करने के कई तरीके होते हैं:

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

  • यदि आप प्रक्रिया को नियंत्रित नहीं कर सकते हैं लेकिन आप जानते हैं कि प्रक्रिया फ़ाइल लिखने के बाद समाप्त हो जाती है, तो आप प्रक्रिया आईडी का पता लगा सकते हैं और फिर जांच सकते हैं कि प्रक्रिया अभी भी kill -0 $PID के साथ चल रही है या नहीं। यदि $?0 है, तो प्रक्रिया अभी भी जिंदा है।

  • यदि यह संभव नहीं है, तो आप इस प्रक्रिया के लिए सभी खुली फ़ाइलों की सूची प्राप्त करने के लिए lsof -np $PID का उपयोग कर सकते हैं और जांच सकते हैं कि आपकी फ़ाइल सूची में है या नहीं। हालांकि, यह कुछ हद तक धीमा है।

[संपादित करें] नोट है कि इन सभी दृष्टिकोण कुछ हद तक भंगुर होते हैं। सही समाधान यह है कि बाहरी प्रक्रिया अस्थायी नाम का उपयोग करके फ़ाइल लिखती है और उसके बाद इसे जल्द ही नामित करती है।

नाम यह सुनिश्चित करता है कि हर कोई या तो पूरी फ़ाइल को सभी डेटा या कुछ भी नहीं देखता है।

+0

कैसे '' के बारे में! lsof -/path/to/file'? – RubyTuesdayDONO

+0

@RubyTuesdayDONO: इसके बारे में क्या? –

+0

मैं यह पूछने के लिए एक और सीधा तरीका बता रहा था कि क्या किसी भी प्रक्रिया में उस विशिष्ट फ़ाइल को खुली है (बनाम 'grep''ing सबसे अधिक संभावित प्रक्रिया द्वारा खुली सभी फ़ाइलों की सूची के माध्यम से)।एक बार समाप्त होने पर अस्थायी फ़ाइलों को बदलने के लिए आपकी माध्यमिक अनुशंसा एक बेहतर विकल्प की तरह लगती है - मैं सिर्फ यह कहना चाहता हूं कि 'lsof' एक वांछित कमांड है जिसमें कई वांछित वांछित जानकारी पर होमिंग के लिए एक परिष्कृत कमांड है। – RubyTuesdayDONO

2

आसान तरीका: स्क्रिप्ट को प्रोग्राम निष्पादित करने दें और इसे समाप्त होने तक प्रतीक्षा करें।

1

यह अच्छा नहीं है, और यह मुझे इसे लिखने गंदा लग रहा है ... /tmp/foo.txt फ़ाइल का परीक्षण किया जा रहा है बनाता है ...

#!/bin/bash 

until [ "$(find /proc/*/fd 2> /dev/null | 
    xargs -i{} readlink {} | 
    grep -c '^/tmp/foo.txt$')" == "0" ]; do 

    sleep 1; 
done; 
0

लूप जब तक फ़ाइल स्थिर दृष्टिकोण है, यह आप प्रयोग के परिणामों के लिए इंतज़ार कर रहे हैं (ताकि आप वास्तविक समय घटना से निपटने की जरूरत नहीं है) काम करना चाहिए:

EXPECTED_WRITE_INTERVAL_SECONDS=1 
FILE="file.txt" 
while : ; do 
     omod=$(stat -c %Y $FILE) 
     # echo "OLD: $omod" 
     sleep $EXPECTED_WRITE_INTERVAL_SECONDS 
     nmod=$(stat -c %Y $FILE) 
     # echo "NEW: $nmod" 
     if [ $omod == $nmod ] ; then 
       break 
     fi 
done 
1

inotify का उपयोग कर एक छोटा सा सी कार्यक्रम बनाएँ। कार्यक्रम चाहिए:

  1. inotify उदाहरण बनाएं।
  2. रुचि के फ़ाइल पथ के लिए IN_CLOSE_WRITE ईवेंट के लिए उदाहरण पर एक घड़ी जोड़ें।
  3. घटना के लिए प्रतीक्षा करें।
  4. उचित कोड से बाहर निकलें।

फिर अपनी स्क्रिप्ट में, प्रोग्राम को फ़ाइल पथ के साथ तर्क के रूप में आमंत्रित करें।

आप टाइमआउट तर्क जोड़कर इसे बढ़ा सकते हैं, और विभिन्न घटनाओं को निर्दिष्ट करने की इजाजत दे सकते हैं।

संबंधित मुद्दे