नई फ़ाइलों के लिए फ़ोल्डर की निगरानी के लिए स्क्रिप्ट?


127

स्क्रिप्ट के साथ फ़ोल्डर में नई फ़ाइलों का पता लगाने के लिए कैसे ? जैसे ही वे फ़ोल्डर में बनाई जाती हैं, मैं फ़ाइलों को संसाधित करना चाहूंगा। क्या ऐसा करना संभव है या क्या मुझे साथ एक स्क्रिप्ट शेड्यूल करना है जो प्रत्येक मिनट या तो नई फ़ाइलों की जांच करता है?


1
क्या आप संसाधित होने के बाद फ़ोल्डर से फ़ाइलों को हटाने जा रहे हैं?
ztank1013

जवाबों:


151

आपको inotifywaitउदाहरण के रूप में उपयोग करने पर विचार करना चाहिए :

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

उबंटू inotifywaitमें inotify-toolsपैकेज द्वारा प्रदान किया गया है। संस्करण 3.13 के रूप में (Ubuntu 12.04 में वर्तमान) inotifywaitमें -f विकल्प के बिना फ़ाइल नाम शामिल होगा। पुराने संस्करणों के लिए मजबूर होना पड़ सकता है। यह नोट करना महत्वपूर्ण है कि -eविकल्प inotifywaitईवेंट फ़िल्टरिंग का सबसे अच्छा तरीका है। साथ ही, आपकी readकमांड कई आउटपुटों में स्थितीय आउटपुट को असाइन कर सकती है जिसे आप उपयोग या अनदेखा करना चुन सकते हैं। आउटपुट को प्रीप्रोसेस करने के लिए grep / sed / awk का उपयोग करने की कोई आवश्यकता नहीं है।


1
महान! inotifywaitमैं सिर्फ क्या चाहता था।
१२:५० बजे १२

2
बस इसे अपडेट करना चाहते हैं। इसे प्राप्त करने के लिए आपको जागने की आवश्यकता नहीं है। आप '-e create' के साथ घटनाओं को फ़िल्टर कर सकते हैं और '-f% f' या '-f% w% f' का उपयोग करके पूर्ण पथ प्राप्त कर सकते हैं। तो उपरोक्त स्क्रिप्ट की पहली पंक्ति बन जाती है: inotifywait -m / path -f% w% f -e create |
लूगॉउस

2
@Lugoues और अब जब आप उपयोग करने की कोशिश करते हैं The '--filename' option no longer exists. The option it enabled in earlier versions of inotifywait is now turned on by default., तो आप इसे प्राप्त करते हैं , तो आपको केवल यह करना होगा कि inotifywait -m /path -e create |मैं इस उत्तर को आज़माने और संपादित करने जा रहा हूं।
ब्रूनो ब्रोंस्की

1
अब इसके लिए एक पोर्टेबल टूल भी है जिसे कहा जाता है fswatch। मैंने इसे नहीं लिखा था, लेकिन यह खुला स्रोत है और मैं इसका उपयोग करता हूं।

1
जब ट्रिगर चालू होता है, तो सूचनादाता inotfiywait एक पंक्ति में सूचना के 3 टुकड़े करता है। 'रीड' बैश बिलिन इनपुट लाइन को पढ़ता है और सूचना के तीन टुकड़ों में से प्रत्येक को एक चर में असाइन करता है। इस प्रकार पहला टुकड़ा चर पथ को दिया जाता है, दूसरा कार्रवाई के लिए और तीसरा फ़ाइल को। उन चरों का मान रखने के बाद, वे बाद में उपयोग किए जाने के लिए उपलब्ध हैं (जैसे प्रतिध्वनि रेखा पर)। अधिक जानकारी: tldp.org/LDP/Bash-Beginners-Guide/html/sect_08_02.html
Tim

26

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

उदाहरण के लिए:

<directory> <file change mask> <command or action>  options
/var/www/html IN_CREATE /root/scripts/backup.sh

आप यहां एक पूरा उदाहरण देख सकते हैं: http://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/


24

मैंने अभी इसे पकाया है, और इसके साथ कोई बड़ी समस्या नहीं देखी है, चेक के बीच में गुम फाइलों के एक छोटे से मौके के अलावा।

while true
do
       touch  ./lastwatch
       sleep 10
       find /YOUR/WATCH/PATH -cnewer ./lastwatch -exec SOMECOMMAND {} \;
done

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


अच्छी पकड़। मैंने इसे फ़ाइल नाम में रिक्त स्थान का समर्थन करने के लिए थोड़ा सुधार दिया।
माइकल साकची

पूर्ण रूप से। यही रास्ता तय करना है। वास्तव में निश्चित नहीं है कि मैं उस सड़क पर क्यों गया, मैं नियमित रूप से उपयोग करता हूं।
माइकल साकची

यह नहीं realtime। रीयलटाइम हमेशा सबसे अच्छा है
फरहान

3
सबसे अच्छा समाधान अगर inotifyउपलब्ध नहीं है। मैं -type fकेवल फ़ाइलों को फ़िल्टर करने के लिए जोड़ूंगा। अन्यथा फ़ोल्डर भी लौटा दिया जाएगा।
जिओ पेंग - ZenUML.com

हां - -f filenameविकल्प बहुत अच्छा है। तो फिर एकमात्र शेष प्रश्न यह है कि इसे रिबूट पर कैसे शुरू किया जाए। मैं अपने सौर संयंत्र के साथ इसका उपयोग करने जा रहा हूं, os.system("ssh me@mysystem ' ( touch /home/me/alarms/low24 ) '")तो इस फ़ाइल के निर्माण के कारण espeakकम वोल्टेज का उपयोग करने और घोषणा करने के लिए मास्टर कंप्यूटर होगा । यह पहले से ही मुझे एक ईमेल भेजता है, लेकिन चूंकि मेरा सिस्टम पहले से ही घंटे के शीर्ष पर समय बोलता है, इसलिए इसमें सभी बाकी हैं। askubuntu.com/questions/977613/…
एसडीसोलर

17

आप watchअपनी स्क्रिप्ट में उपयोग कर सकते हैं

watch -n 0.1 ls <your_folder>

अपने फ़ोल्डर को मॉनिटर करता है और हर 0.1 सेकंड में आपको सब कुछ सूचीबद्ध करता है

कमी

वास्तविक समय नहीं है, इसलिए यदि कोई फ़ाइल 0.1 सेकंड से कम में बनाई गई और हटा दी गई है, तो यह काम नहीं करेगा, watchकेवल न्यूनतम 0.1 सेकंड का समर्थन करता है।


यह वही था जो मैं याद करने की कोशिश कर रहा था! बहुत बहुत धन्यवाद!!
जोबा लुसैना

9

मैं लक्ष्य फ़ोल्डर मान रहा हूं (मैं इसे isemptyकेवल सुविधा के लिए कहूंगा ) खाली है और आप एक या एक से अधिक फ़ाइलों को वहां से हटाए जाने की प्रतीक्षा कर रहे हैं।

आप निम्न आदेश का उपयोग कर सकते हैं:

ls -1A isempty | wc -l

सिर्फ यह जांचने के लिए कि क्या फ़ोल्डर अभी भी खाली है, वास्तव में यह 0 लौटाएगा यदि कोई नई फ़ाइल नहीं है (इसलिए isemptyफ़ोल्डर अभी भी खाली है) या, दूसरी ओर, यह 0 से अधिक मान लौटाएगा (वास्तव में संख्या फ़ाइलें वर्तमान में फ़ोल्डर में)।

कहा कि एक मूर्खतापूर्ण अगर / तो परीक्षण बाकी काम कर सकता है:

if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi

बेशक do_somethingफ़ंक्शन को isemptyफ़ोल्डर के भीतर फ़ाइल (ओं) में हेरफेर करना होगा और फिर प्रसंस्करण के बाद फ़ोल्डर से इसे (उन्हें) हटा दें।

आपके क्रॉस्टैब में निम्नलिखित की तरह एक लाइन जोड़ने से एक मिनट में एक बार चेक चलेगा और do_somethingयदि फ़ोल्डर निश्चित रूप से खाली नहीं होता है तो कार्रवाई को ट्रिगर करेगा :

* * * * *     if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi

यह समाधान माउंटेड दूरस्थ फाइल सिस्टम के लिए काम करता है। inotify-tools developer (s) फ्यूज पर काम कर रहा है (या 2014 के मध्य में था)।
रोंडो

3
आपको कभी भी lsस्क्रिप्टिंग के लिए उपयोग नहीं करना चाहिए । findइसके बजाय साधारण ग्लोबिंग का
andsens

6

यदि आप नई फ़ाइलों का पता लगाना चाहते हैं, तो उन्हें संसाधित करें और अंत में आगे बढ़े हुए फ़ाइलों को आप systemd.path का उपयोग कर सकते हैं । इस विधि के आधार पर inotify। एक विकल्प DirectoryNotEmpty है, इसलिए सिस्टमड आपकी स्क्रिप्ट को हमेशा चला सकता है जब वह निर्देशिका में किसी भी फ़ाइल का पता लगाता है। आपको यह याद रखना होगा कि यह तभी काम करेगा जब आप आगे की फाइलों और स्क्रिप्ट के पत्तों की निर्देशिका को खाली कर सकते हैं।

सबसे पहले mymonitor.service फ़ाइल तैयार करें

[Unit]
Description=Start the script

[Service]
Type=oneshot
ExecStart=/path/to/your/script

अगले रास्ते को परिभाषित करने के लिए mymonitor.path पर जाएं

[Unit]
Description= Triggers the service

[Path]
DirectoryNotEmpty=/path/to/monitor

[Install]
WantedBy=multi-user.target

यदि .path फ़ाइल का नाम सेवा के नाम के समान है, तो .path फ़ाइल में सेवा नाम निर्दिष्ट करने की कोई आवश्यकता नहीं है।

यह डमीज के लिए मॉनिटरिंग फ़ाइल एक्सेस पर आधारित है


4

entr

इसका उपयोग करना entrनया तरीका है (यह क्रॉस प्लेटफॉर्म है)। नोट entrमतदान का उपयोग नहीं करता है यह कई विकल्पों में से एक बड़ा लाभ देता है।

उपयोग kqueue(2)या inotify(7)मतदान से बचने के लिए। entrतेजी से प्रतिक्रिया और स्वचालित परीक्षण को प्राकृतिक और पूरी तरह से सामान्य बनाने के लिए लिखा गया था।

बीएसडी पर यह उपयोग करता है pledge(2)

आप इसे स्थापित कर सकते हैं

apt-get install entr
dnf install entr

आप का उपयोग करके नए परिवर्धन के लिए एक निर्देशिका को ट्रैक कर सकते हैं

while $(true); do
  # echo ./my_watch_dir | entr -dnr echo "Running trigger..."
  echo ./my_watch_dir | entr -dnr ##MY COMMAND##
done;

समझाया गया विकल्प (डॉक्स से),

  • -d इनपुट के रूप में दी गई नियमित फ़ाइलों की निर्देशिकाओं को ट्रैक करें और यदि कोई नई फ़ाइल जोड़ी जाती है तो बाहर निकलें। यह विकल्प निर्देशिकाओं को स्पष्ट रूप से निर्दिष्ट करने में सक्षम बनाता है। '।' से शुरू होने वाले नामों की फाइलें नजरअंदाज कर दिया जाता है।
  • -nगैर-इंटरैक्टिव मोड में चलाएं। इस मोड में entr TTY से पढ़ने या इसके गुणों को बदलने का प्रयास नहीं करता है।
  • -r एक निरंतर बच्चे की प्रक्रिया को फिर से लोड करें। ऑपरेशन के मानक मोड के साथ, एक उपयोगिता जो समाप्त हो जाती है उसे फिर से निष्पादित नहीं किया जाता है जब तक कि एक फ़ाइल सिस्टम या कीबोर्ड इवेंट संसाधित नहीं होता है। SIGTERMउपयोगिता को समाप्त करने से पहले इसका उपयोग किया जाता है। शेल स्क्रिप्ट को सिग्नल से रोकने के लिए एक प्रक्रिया समूह बनाया जाता है। entrयह सुनिश्चित करने के लिए कि सॉकेट जैसे संसाधनों को बंद कर दिया गया है, उपयोगिता से बाहर निकलने की प्रतीक्षा करता है। TTY का नियंत्रण बच्चे की प्रक्रिया को स्थानांतरित नहीं करता है।

2

बैश यह आसानी से नहीं कर सकते। आपको मूल रूप से फ़ोल्डर में सभी फाइलों की एक सूची प्राप्त करनी होगी और समय-समय पर एक नई सूची प्राप्त करनी होगी और उनकी तुलना करना होगा कि क्या बदला है।

जिसे आप खोज रहे हैं उसे इनोटिफ़ाइड कहा जाता है। इसका निर्माण लिनक्स कर्नेल में किया गया है और आप मूल रूप से वहां बैठकर कुछ होने की प्रतीक्षा कर सकते हैं, जिस बिंदु पर इनोटिफ़ाइज़ वापस आता है और कहता है, 'हे, फ़ोबार नामक एक नई फ़ाइल।

आप जो चाहते हैं उसे पूरा करने के लिए आपको perl जैसी किसी चीज़ पर स्विच करना होगा और लिनक्स का उपयोग करना होगा :: Inotify2 (अजगर संभवत: Inotify का समर्थन करता है, लेकिन मैं एक पर्ल व्यक्ति हूं)।


0

यह cygwin और Linux में काम करता है। पिछले समाधानों में से कुछ जो एक फ़ाइल लिखते हैं, डिस्क को थ्रैश करने का कारण होगा। इस समस्या के कारण यह समस्या नहीं है:

SIG=1
SIG0=$SIG
while [ $SIG != 0 ] ; do
 while [ $SIG = $SIG0 ] ; do
   SIG=`ls -1 | md5sum | cut -c1-32`
   sleep 10
 done
 SIG0=$SIG
 ls -lrt | tail -n 1
done

0

नीचे दिए गए उदाहरण के एक संक्षिप्त संस्करण है stackoverflow कि विशिष्ट निर्देशिका की निगरानी की आवश्यकता है कि मैं परीक्षण किया है और अपनी परियोजनाओं में से एक में शामिल किया गया है।

Var_dir="${1:-/tmp}"
Var_diff_sleep="${2:-120}"
Var_diff_opts="--suppress-common-lines"
Func_parse_diff(){
    _added="$(grep -E '>' <<<"${@}")"
    if [ "${#_added}" != "0" ]; then
        mapfile -t _added_list <<<"${_added//> /}"
        _let _index=0
        until [ "${#_added_list[@]}" = "${_index}" ]; do
            _path_to_check="${Var_dir}/${_added_list[${_index}]}"
            if [ -f "${_path_to_check}" ]; then
                echo "# File: ${_path_to_check}"
            elif [ -d "${_path_to_check}" ]; then
                echo "# Directory: ${_path_to_check}"
            if [ -p "${_path_to_check}" ]; then
                echo "# Pipe: ${_path_to_check}"
            fi
            let _index++
        done
        unset _index
    fi
}
Func_watch_bulk_dir(){
    _current_listing=""
    while [ -d "${Var_dir}" ]; do
        _new_listing="$(ls "${Var_dir}")"
        _diff_listing="$(diff ${Var_dec_diff_opts} <(${Var_echo} "${_current_listing}") <(${Var_echo} "${_new_listing}"))"
        if [ "${_diff_listing}" != "0" ]; then
            Func_parse_diff "${_diff_listing}"
        fi
        _current_listing="${_new_listing}"
        sleep ${Var_diff_sleep}
    done
}

यहां एक स्क्रिप्ट का लिंक दिया गया है, जो अपने sshfs माउंट बिंदु में पाई गई फ़ाइलों या निर्देशिकाओं को स्वचालित रूप से डिक्रिप्ट करने के लिए ऊपर के संशोधित संस्करण का उपयोग करता है; उपर्युक्त परियोजना।

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