विम के साथ inotifywait का उपयोग करना


14

मेरे पास सरल स्क्रिप्ट है जो परिवर्तनों के लिए फ़ाइल की निगरानी करती है और इसे दूरस्थ प्रतिलिपि के साथ rsyncs करती है:

#!/bin/bash

while inotifywait -e close_write somefile
do
    rsync somefile user@host.domain:./somefile
done

यह नैनो के साथ ठीक काम करता है, लेकिन विम के साथ विफल रहता है। जब मैं नैनो का उपयोग करता हूं, तो यह आउटपुट:

somefile CLOSE_WRITE,CLOSE   

और अगले संस्करण के लिए इंतजार कर अगले लूप शुरू होता है।

जब मैं विम का उपयोग करता हूं, तो कोई आउटपुट नहीं होता है, स्क्रिप्ट सिर्फ एक्जिट कोड 0 के साथ बंद हो जाती है।

मैंने कुछ शोध किए और पता चला कि करीबी के लिए initofywait uing के लिए close_write सही पैरामीटर है (पहले मैं इवेंट को संशोधित करना चाहता था), फिर भी कुछ कारणों से यह मेरे लिए विफल रहा।


इससे मेरा काम बनता है। आपने फ़ाइल को सहेजने से पहले उसे बदलने के बजाय विम में बदल दिया?
रोआम

@roaima यह केवल तभी काम करता है जब backupcopyविकल्प बंद हो।
गिल्स एसओ- बुराई को रोकें '

जवाबों:


15

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

नैनो स्पष्ट रूप से मौजूदा फ़ाइल को अधिलेखित करती है। आपकी स्क्रिप्ट उस बिंदु का पता लगाती है जब यह लिखना समाप्त हो जाता है ( close_writeघटना) और rsyncउस बिंदु पर चलता है । ध्यान दें कि rsync के लिए फ़ाइल के अधूरे संस्करण को हथियाना संभव है, यदि आप त्वरित उत्तराधिकार में दो बार बचत करते हैं, तो इससे पहले कि rsync ने पहली बचत से अपना काम पूरा कर लिया है।

दूसरी ओर विम, राइट-टू-मूव रणनीति का उपयोग करता है - जिसके प्रभाव के लिए कुछ

echo 'new content' >somefile.new
mv -f somefile.new somefile

फ़ाइल के पुराने संस्करण का क्या होता है, यह उस बिंदु पर हटा दिया जाता है जहां नया संस्करण जगह में ले जाया जाता है। इस बिंदु पर, inotifywaitकमांड वापस आती है, क्योंकि यह बताया गया है कि फ़ाइल अब मौजूद नहीं है। (नया somefileएक ही नाम के साथ एक अलग फ़ाइल है।) यदि विम को एक बैकअप फ़ाइल बनाने के लिए कॉन्फ़िगर किया गया था, तो क्या होगा कुछ ऐसा है

echo 'new content' >somefile.new
ln somefile somefile.old
mv -f somefile.new somefile

और inotifywaitअब बैकअप देख रहा होगा।

फाइल सेव स्ट्रेटेजीज के बारे में अधिक जानकारी के लिए, देखें कि प्रोग्राम चलाते समय लाइव अपडेट करना कैसे संभव है? और फ़ाइल अनुमतियाँ और बचत

विम को ओवरराइट रणनीति का उपयोग करने के लिए कहा जा सकता है: backupcopyविकल्प बंद करें ( :set nobackupcopy)। यह जोखिम भरा है, जैसा कि ऊपर बताया गया है।

दोनों सहेजने की रणनीतियों को संभालने के लिए, निर्देशिका देखें और दोनों के लिए close_writeऔर moved_toघटनाओं को फ़िल्टर करें somefile

inotifywait -m -e close_write,moved_to --format %e/%f . |
while IFS=/ read -r events file; do
  if [ "$file" = "somefile" ]; then
    …
  fi
done

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

@LimitedAtonement यह इस प्रश्न में एक से अधिक जटिल उपयोग मामला है। आपके उपयोग के मामले में, एक फ़ाइल सहेजे जाने के बाद आपको थोड़ा इंतजार करना होगा। फ़ाइलों को कभी भी "एक बार में" संशोधित नहीं किया जाता है। यदि आप कई फ़ाइलों को सहेजते हैं :wa, तो आप लगातार घटनाओं को कम कर सकते हैं। आपको पहले देखने के बाद इंतजार करना होगा कि क्या दूसरे लोग आ रहे हैं। लेकिन आप यहां प्रस्तुत कोड का उपयोग कर सकते हैं: अतिरिक्त जटिलता अंदर जाएगी
गिल्स एसओ- बुराई को रोकना '

@ गिल्स मैंने while true; do inotifywait ... [no -m]; make; sleep .1; done;या तो तय किया । कुछ गोचर हैं, लेकिन मैं काफी काम की चीज पर पहुंच गया हूं।
सीमित प्रायश्चित
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.