सवाल जब भी फ़ाइल बदलती है तो कमांड कैसे निष्पादित करें?


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

वर्तमान में, मैं इसका उपयोग कर रहा हूं:

while read; do ./myfile.py ; done

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

while sleep_until_file_has_changed myfile.py ; do ./myfile.py ; done

या किसी भी अन्य समाधान के रूप में आसान है।

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

अद्यतन करें: यदि संभव हो तो मुझे कुछ सरल, त्यागना चाहिए। और भी, मैं टर्मिनल में कुछ चलाने के लिए चाहता हूं क्योंकि मैं प्रोग्राम आउटपुट देखना चाहता हूं (मैं त्रुटि संदेश देखना चाहता हूं)।

उत्तरों के बारे में: आपके सभी उत्तरों के लिए धन्यवाद! वे सभी बहुत अच्छे हैं, और प्रत्येक व्यक्ति दूसरों से बहुत अलग दृष्टिकोण लेता है। चूंकि मुझे केवल एक को स्वीकार करने की आवश्यकता है, मैं उस व्यक्ति को स्वीकार कर रहा हूं जिसे मैंने वास्तव में उपयोग किया है (यह सरल, त्वरित और याद रखने योग्य था), भले ही मुझे पता है कि यह सबसे सुरुचिपूर्ण नहीं है।


375
2017-08-27 20:02


मूल


संभावित क्रॉस साइट का डुप्लिकेट: stackoverflow.com/questions/2972765/... (हालांकि यहां यह विषय पर है =)) - Ciro Santilli 新疆改造中心 六四事件 法轮功
मैंने एक क्रॉस साइट डुप्लिकेट से पहले संदर्भित किया है और इसे अस्वीकार कर दिया गया था: एस;) - Francisco Tapia
जोनाथन हार्टले का समाधान यहां अन्य समाधानों पर बनाता है और बड़ी समस्याओं को हल करता है जो शीर्ष वोट वाले उत्तरों में हैं: कुछ संशोधनों को याद करना और अक्षम होना। कृपया उसे स्वीकार किए गए उत्तर को बदलें, जिसे गीथब पर भी रखा जा रहा है github.com/tartley/rerun2 (या उन त्रुटियों के बिना किसी अन्य समाधान के लिए) - nealmcb


जवाब:


सरल, उपयोग कर रहा है inotifywait (अपने वितरण की स्थापना करें inotify-tools पैकेज):

while inotifywait -e close_write myfile.py; do ./myfile.py; done

या

inotifywait -q -m -e close_write myfile.py |
while read -r filename event; do
  ./myfile.py         # or "./$filename"
done

पहला स्निपेट सरल है, लेकिन इसमें एक महत्वपूर्ण नकारात्मक पक्ष है: यह प्रदर्शन किए जाने वाले परिवर्तनों को याद करेगा inotifywait नहीं चल रहा है (विशेष रूप से जबकि myfile दौड रहा है)। दूसरे स्निपेट में यह दोष नहीं है। हालांकि, सावधान रहें कि यह मानता है कि फ़ाइल नाम में व्हाइटस्पेस नहीं है। यदि यह एक समस्या है, तो इसका उपयोग करें --format फ़ाइल नाम शामिल करने के लिए आउटपुट को बदलने का विकल्प:

inotifywait -q -m -e close_write --format %e myfile.py |
while read events; do
  ./myfile.py
done

किसी भी तरह से, एक सीमा है: अगर कुछ कार्यक्रम बदलता है myfile.py मौजूदा को लिखने के बजाय, एक अलग फ़ाइल के साथ myfile, inotifywait मर जाऊंगा। कई संपादक इस तरह से काम करते हैं।

इस सीमा को दूर करने के लिए, उपयोग करें inotifywait निर्देशिका पर:

inotifywait -e close_write,moved_to,create -m . |
while read -r directory events filename; do
  if [ "$filename" = "myfile.py" ]; then
    ./myfile.py
  fi
done

वैकल्पिक रूप से, एक अन्य उपकरण का उपयोग करें जो समान अंतर्निहित कार्यक्षमता का उपयोग करता है, जैसे कि incron (जब फ़ाइल संशोधित होती है तो आप ईवेंट पंजीकृत कर सकते हैं) या fswatch (एक उपकरण जो लिनक्स के इनोटिफ़ाई के प्रत्येक संस्करण के एनालॉग का उपयोग करके कई अन्य यूनिक्स संस्करणों पर भी काम करता है)।


357
2017-08-27 20:54



मैंने सरल-उपयोग में इन सभी को (कुछ बाश चाल के साथ) encapsulated किया है sleep_until_modified.shस्क्रिप्ट, यहां उपलब्ध है: bitbucket.org/denilsonsa/small_scripts/src - Denilson Sá Maia
while sleep_until_modified.sh derivation.tex ; do latexmk -pdf derivation.tex ; done शानदार है। धन्यवाद। - Rhys Ulerich
inotifywait -e delete_self मेरे लिए अच्छा काम करता प्रतीत होता है। - Kos
यह आसान है लेकिन इसमें दो महत्वपूर्ण मुद्दे हैं: घटनाओं को याद किया जा सकता है (लूप में सभी घटनाएं) और इनोटिफाइवेट की शुरुआत प्रत्येक बार किया जाता है जो इस समाधान को बड़े रिकर्सिव फ़ोल्डर्स के लिए धीमा कर देता है। - Wernight
किसी कारण के लिए while inotifywait -e close_write myfile.py; do ./myfile.py; done आदेश (बैश और zsh) चलाने के बिना हमेशा बाहर निकलता है। इसके लिए काम करने के लिए मुझे जोड़ने की जरूरत है || trueउदाहरण के लिए: while inotifywait -e close_write myfile.py || true; do ./myfile.py; done - ideasman42


entr (http://entrproject.org/) inotify (और * बीएसडी और मैक ओएस एक्स का भी समर्थन करता है) के लिए एक और अधिक अनुकूल इंटरफ़ेस प्रदान करता है।

यह देखने के लिए एकाधिक फ़ाइलों को निर्दिष्ट करना बहुत आसान बनाता है (केवल सीमित है ulimit -n), फ़ाइलों को प्रतिस्थापित करने से निपटने में परेशानी होती है, और कम बैश वाक्यविन्यास की आवश्यकता होती है:

$ find . -name '*.py' | entr ./myfile.py

मैं वर्तमान में संशोधित कोड के लिए यूनिट परीक्षण चलाने के लिए अपने पूरे प्रोजेक्ट स्रोत पेड़ पर इसका उपयोग कर रहा हूं, और यह मेरे वर्कफ़्लो में पहले से ही एक बड़ा बढ़ावा रहा है।

जैसे ध्वज -c (रन के बीच स्क्रीन साफ़ करें) और -d (बाहर निकलें जब किसी नई फ़ाइल को किसी निगरानी निर्देशिका में जोड़ा जाता है) और भी लचीलापन जोड़ें, उदाहरण के लिए आप यह कर सकते हैं:

$ while sleep 1 ; do find . -name '*.py' | entr -d ./myfile.py ; done

2018 की शुरुआत में यह अभी भी सक्रिय विकास में है और यह डेबियन और उबंटू में पाया जा सकता है (apt install entr); लेखक के रेपो से इमारत किसी भी मामले में दर्द रहित थी।


127
2017-10-25 09:41



नई फाइलों और उनके संशोधनों को संभाल नहीं करता है। - Wernight
@Wernight - 7 मई 2014 के प्रवेश के रूप में नया है -d झंडा; यह थोड़ा और लंबा हवादार है, लेकिन आप कर सकते हैं while sleep 1 ; do find . -name '*.py' | entr -d ./myfile.py ; done नई फाइलों से निपटने के लिए। - Paul Fenney
प्रवेश डेबियन रेस में कम से कम डेबियन जेसी / 8.2 से भी उपलब्ध है ... - Peter V. Mørch
निश्चित रूप से ओएस एक्स पर मुझे सबसे अच्छा मिला। fswatch बहुत अधिक फंकी घटनाओं को पकड़ता है और मैं समझने के लिए समय बिताना नहीं चाहता क्यों - dtc
यह ध्यान देने लायक है entr होमब्री पर उपलब्ध है, इसलिए brew install entr उम्मीद के रूप में काम करेंगे - jmarceli


मैंने वास्तव में इसे करने के लिए एक पायथन प्रोग्राम लिखा था जब-बदल

उपयोग सरल है:

when-changed FILE COMMAND...

या एकाधिक फाइलें देखने के लिए:

when-changed FILE [FILE ...] -c COMMAND

FILE एक निर्देशिका हो सकती है। साथ संक्षेप में देखें -r। उपयोग %f आदेश के लिए फ़ाइल नाम पास करने के लिए।


102
2018-06-30 13:34



@ysangkok हाँ यह कोड के नवीनतम संस्करण में करता है :) - joh
अब "पीआईपी इंस्टॉल कब-बदले" से उपलब्ध है। अभी भी अच्छी तरह से काम करता है। धन्यवाद। - A. L. Flanagan
पहले स्क्रीन को साफ़ करने के लिए आप इसका उपयोग कर सकते हैं when-changed FILE 'clear; COMMAND'। - Dave James Miller
यह जवाब इतना बेहतर है क्योंकि मैं इसे विंडोज़ पर भी कर सकता हूं। और इस आदमी ने वास्तव में जवाब पाने के लिए एक कार्यक्रम लिखा था। - Wolfpack'08
सबके लिए अच्छी खबर है! when-changed अब क्रॉस-प्लेटफॉर्म है! नवीनतम देखें 0.3.0 रिलीज :) - joh


इस स्क्रिप्ट के बारे में कैसे? यह उपयोग करता है stat किसी फ़ाइल का एक्सेस समय प्राप्त करने के लिए आदेश और एक्सेस समय में कोई भी परिवर्तन होने पर कमांड चलाता है (जब भी फ़ाइल एक्सेस की जाती है)।

#!/bin/bash

### Set initial time of file
LTIME=`stat -c %Z /path/to/the/file.txt`

while true    
do
   ATIME=`stat -c %Z /path/to/the/file.txt`

   if [[ "$ATIME" != "$LTIME" ]]
   then    
       echo "RUN COMMAND"
       LTIME=$ATIME
   fi
   sleep 5
done

46
2017-08-20 17:12



नहीं होगा statसंशोधित समय को बेहतर होने पर "जब भी कोई फ़ाइल बदलती है" उत्तर? - Xen2050
प्रति सेकंड कई बार स्टेट चलाना कई कारण डिस्क पर पढ़ता है? या fstat सिस्टम कॉल स्वचालित रूप से इन प्रतिक्रियाओं को कैश बना देगा? जब भी मैं परिवर्तन करता हूं तो मैं अपने सी कोड को संकलित करने के लिए 'ग्रंट घड़ी' लिखने की कोशिश कर रहा हूं - Oskenso Kashi
यह अच्छा है अगर आप फ़ाइल नाम को अग्रिम में देखना चाहते हैं। फ़ाइल नाम को लिपि में पास करना बेहतर होगा। बेहतर होगा यदि आप कई फ़ाइल नामों को पारित कर सकते हैं (उदाहरण के लिए। "Mywatch * .py")। बेहतर होगा अगर यह उपनिवेशों में फ़ाइलों पर भी पुनरावर्ती रूप से संचालित हो सकता है, जो कुछ अन्य समाधान करते हैं। - Jonathan Hartley
अगर कोई भारी पढ़ने के बारे में सोच रहा है, तो मैंने 0.05 के नींद के साथ उबंटू 17.04 में इस स्क्रिप्ट का परीक्षण किया और vmstat -d डिस्क पहुंच के लिए देखने के लिए। ऐसा लगता है कि लिनक्स इस तरह की चीज़ों को कैशिंग करने में शानदार काम करता है: डी - Oskenso Kashi
"COMMAND" में टाइपो है, मैं ठीक करने की कोशिश कर रहा था, लेकिन एसओ। कहते हैं "संपादन 6 वर्णों से कम नहीं होना चाहिए" - user337085


विम का उपयोग समाधान:

:au BufWritePost myfile.py :silent !./myfile.py

लेकिन मैं इस समाधान को नहीं चाहता क्योंकि यह टाइप करने के लिए बहुत परेशान है, यह याद रखना थोड़ा मुश्किल है कि क्या टाइप करना है, बिल्कुल, और इसके प्रभावों को पूर्ववत करना थोड़ा मुश्किल है (चलाने की आवश्यकता है :au! BufWritePost myfile.py)। इसके अलावा, यह समाधान Vim को तब तक अवरुद्ध करता है जब तक कमांड निष्पादित नहीं हो जाता है।

मैंने यहां सिर्फ इस समाधान को पूर्णता के लिए जोड़ा है, क्योंकि यह अन्य लोगों की मदद कर सकता है।

प्रोग्राम आउटपुट प्रदर्शित करने के लिए (और अपने संपादन प्रवाह को पूरी तरह से बाधित करें, क्योंकि आउटपुट आपके संपादक पर कुछ सेकंड के लिए लिख देगा, जब तक आप एंटर दबाएंगे), हटाएं :silent आदेश।


28
2017-08-27 20:12



साथ मिलकर यह काफी अच्छा हो सकता है entr (नीचे देखें) - बस एक डमी फ़ाइल को स्पर्श करें जो प्रवेश द्वार देख रहा है, और बाकी को पृष्ठभूमि में प्रवेश करने दें ... या tmux send-keys यदि आप ऐसे माहौल में होते हैं :) - Paul Fenney
अच्छा! आप अपने लिए एक मैक्रो बना सकते हैं .vimrc फ़ाइल - ErichBSchulz


यदि आपके पास होता है npm स्थापित है, nodemon संभवतः ओएस एक्स पर शुरू करने का सबसे आसान तरीका है, जो स्पष्ट रूप से उपकरण को निष्क्रिय नहीं करता है। जब कोई फ़ोल्डर बदलता है तो यह कमांड चलाने का समर्थन करता है।


24
2018-06-09 23:51



हालांकि, यह केवल .js और .coffee फ़ाइलों को देखता है। - zelk
वर्तमान संस्करण किसी भी कमांड का समर्थन करता है, उदाहरण के लिए: nodemon -x "bundle exec rspec" spec/models/model_spec.rb -w app/models -w spec/models - kek
काश मैं अधिक जानकारी थी, लेकिन osx में परिवर्तन, fsevents ट्रैक करने के लिए एक तरीका है - ConstantineK
ओएस एक्स पर आप भी उपयोग कर सकते हैं डेमन्स लॉन्च करें के साथ WatchPaths जैसा कि मेरे लिंक में दिखाया गया है। - Adam Johns


rerun2 (जिथब पर) फॉर्म की 10-पंक्ति बैश स्क्रिप्ट है:

#!/usr/bin/env bash

function execute() {
    clear
    echo "$@"
    eval "$@"
}

execute "$@"

inotifywait --quiet --recursive --monitor --event modify --format "%w%f" . \
| while read change; do
    execute "$@"
done

अपने पैथ पर github संस्करण को 'rerun' के रूप में सहेजें, और इसका उपयोग करके इसका आह्वान करें:

rerun COMMAND

जब भी कोई फाइल सिस्टम आपकी वर्तमान निर्देशिका (रिकर्सिव) में ईवेंट संशोधित करता है तो यह COMMAND चलाता है।

चीजों को इसके बारे में पसंद हो सकता है:

  • यह inotify का उपयोग करता है, तो मतदान से अधिक प्रतिक्रियाशील है। सब-मिलीसेकंड यूनिट परीक्षण चलाने के लिए शानदार, या ग्राफविज़ डॉट फ़ाइलों को प्रतिपादित करते समय, हर बार जब आप 'सेव' दबाते हैं।
  • क्योंकि यह बहुत तेज़ है, आपको प्रदर्शन कारणों के लिए बड़े उपनिवेशों (जैसे node_modules) को अनदेखा करने के लिए कहने की परेशानी नहीं है।
  • यह अतिरिक्त सुपर उत्तरदायी है, क्योंकि यह प्रत्येक बार पुनरावृत्ति पर, स्टार्टअप पर, इसे चलाने के बजाय, और घड़ियों को स्थापित करने की महंगी हिट करने के लिए केवल एक बार inotifywait कॉल करता है।
  • यह बैश की सिर्फ 12 लाइनें है
  • चूंकि यह बैश है, यह आपके द्वारा पारित आदेशों को व्याख्या करता है जैसे कि आपने उन्हें बैश प्रॉम्प्ट पर टाइप किया था। (संभवतः यह एक अच्छा खोल है यदि आप एक और खोल का उपयोग करें।)
  • यह घटनाओं को खो नहीं देती है, जबकि COMMAND निष्पादित हो रहा है, इस पृष्ठ पर अन्य अन्य अंतर्निहित समाधानों के विपरीत।
  • पहली घटना में, यह 0.15 सेकेंड के लिए 'मृत अवधि' में प्रवेश करता है, जिसके दौरान कमांड एक बार चलने से पहले अन्य घटनाओं को अनदेखा कर दिया जाता है। ऐसा इसलिए है कि बिल्ड-राइट-मूव नृत्य के कारण होने वाली घटनाओं का झटका जो वी या एमाक्स एक बफर को सहेजते समय करता है, संभवतः धीमी गति से चलने वाले परीक्षण सूट के कई श्रमिक निष्पादन का कारण नहीं बनता है। COMMAND निष्पादित होने पर होने वाली किसी भी घटना को अनदेखा नहीं किया जाता है - वे दूसरी मृत अवधि और बाद में निष्पादन का कारण बनेंगे।

चीजें इसके बारे में नापसंद हो सकती हैं:

  • यह inotify का उपयोग करता है, तो लिनक्सलैंड के बाहर काम नहीं करेगा।
  • चूंकि यह इनोटिफ़ाई का उपयोग करता है, यह उपयोगकर्ता इनोटिफ़ी घड़ियों की अधिकतम संख्या की तुलना में अधिक फ़ाइलों वाली निर्देशिकाओं को देखने की कोशिश करने पर बारफ करेगा। डिफ़ॉल्ट रूप से, ऐसा लगता है कि मैं विभिन्न मशीनों पर 5,000 से 8,000 तक सेट करता हूं, लेकिन बढ़ाना आसान है। देख https://unix.stackexchange.com/questions/13751/kernel-inotify-watch-limit-reached
  • यह बैश उपनाम वाले कमांड निष्पादित करने में विफल रहता है। मैं कसम खाता हूं कि यह काम करता था। सिद्धांत रूप में, क्योंकि यह बैश है, कम से कम COMMAND निष्पादित नहीं करता है, मैं उम्मीद करता हूं कि यह काम करे। मुझे सुनना अच्छा लगेगा अगर कोई जानता है कि ऐसा क्यों नहीं करता है। इस पृष्ठ पर कई अन्य समाधान ऐसे आदेश निष्पादित नहीं कर सकते हैं।
  • व्यक्तिगत रूप से मेरी इच्छा है कि मैं टर्मिनल में एक कुंजी हिट करने में सक्षम था जो मैन्युअल रूप से COMMAND के अतिरिक्त निष्पादन का कारण बन रहा है। क्या मैं इसे किसी भी तरह जोड़ सकता हूं? एक साथ चल रहे 'जबकि read -n1' लूप जो निष्पादित करता है?
  • अभी मैंने टर्मिनल को साफ़ करने और प्रत्येक पुनरावृत्ति पर निष्पादित COMMAND मुद्रित करने के लिए इसे कोड किया है। कुछ लोग इस तरह की चीज़ों को चालू करने के लिए कमांड लाइन झंडे जोड़ना पसंद कर सकते हैं, लेकिन इससे आकार और जटिलता में कई गुना वृद्धि होगी।

यह @ cychoi के एवर का एक परिष्करण है।


13
2017-09-09 21:49



मेरा मानना ​​है कि आपको उपयोग करना चाहिए "$@" के बजाय $@, रिक्त स्थान वाले तर्कों के साथ ठीक से काम करने के लिए। लेकिन साथ ही आप इसका उपयोग करते हैं eval, जो उद्धरण के दौरान उपयोगकर्ता को अतिरिक्त सावधानी बरतने के लिए मजबूर करता है। - Denilson Sá Maia
धन्यवाद डेनिल्सन। क्या आप एक उदाहरण दे सकते हैं कि उद्धरण को सावधानीपूर्वक करने की आवश्यकता है? मैं इसे पिछले 24 घंटों का उपयोग कर रहा हूं और अब तक रिक्त स्थानों के साथ कोई समस्या नहीं देखी है, न ही सावधानी से उद्धृत कुछ भी - बस के रूप में बुलाया rerun 'command'। क्या आप बस इतना कह रहे हैं कि अगर मैंने "$ @" का उपयोग किया है, तो उपयोगकर्ता इस तरह से आह्वान कर सकता है rerun command (उद्धरण के बिना?) यह मेरे लिए उपयोगी नहीं लगता है: मैं आम तौर पर बैश नहीं करना चाहता कोई भी इसे फिर से शुरू करने से पहले आदेश की प्रसंस्करण। जैसे अगर कमांड में "echo $ myvar" है, तो मैं प्रत्येक पुनरावृत्ति में myvar के नए मान देखना चाहता हूं। - Jonathan Hartley
कुछ इस तरह rerun foo "Some File" तोड़ सकता है लेकिन चूंकि आप इसका उपयोग कर रहे हैं eval, इसे फिर से लिखा जा सकता है rerun 'foo "Some File"। ध्यान दें कि कभी-कभी पथ विस्तार रिक्त स्थान पेश कर सकता है: rerun touch *.foo संभवतः तोड़ने और उपयोग करने की संभावना होगी rerun 'touch *.foo' थोड़ा अलग अर्थशास्त्र है (पथ विस्तार केवल एक बार हो रहा है, या कई बार)। - Denilson Sá Maia
सहायता के लिए धन्यवाद। हां: rerun ls "some file" रिक्त स्थान की वजह से टूटता है। rerun touch *.foo* आमतौर पर ठीक काम करता है, लेकिन विफल रहता है अगर * .foo से मेल खाने वाले फ़ाइल नाम रिक्त स्थान हैं। मुझे देखने में मदद करने के लिए धन्यवाद rerun 'touch *.foo' अलग-अलग अर्थशास्त्र हैं, लेकिन मुझे संदेह है कि सिंगल कोट्स वाला संस्करण अर्थपूर्ण है जो मैं चाहता हूं: मैं चाहता हूं कि प्रत्येक पुनरावृत्ति को फिर से काम करने की इच्छा हो जैसे कि मैंने फिर से आदेश टाइप किया - इसलिए मैं चाहते हैं  *.foo प्रत्येक पुनरावृत्ति पर विस्तार किया जाना है। मैं उनके प्रभावों की जांच करने के लिए आपके सुझावों का प्रयास करूंगा ... - Jonathan Hartley
इस पीआर पर अधिक चर्चा (github.com/tartley/rerun2/pull/1) और दूसरे। - Jonathan Hartley


यहां एक सरल खोल बोर्न शेल स्क्रिप्ट है जो:

  1. दो तर्क लेता है: फ़ाइल की निगरानी की जा सकती है और एक आदेश (तर्क के साथ, यदि आवश्यक हो)
  2. उस फ़ाइल की प्रतिलिपि बनाएँ जिसे आप / tmp निर्देशिका में देख रहे हैं
  3. यह देखने के लिए हर दो सेकंड जांचता है कि आप जिस फ़ाइल की निगरानी कर रहे हैं वह प्रतिलिपि से नई है
  4. यदि यह नया है तो यह प्रतिलिपि को मूल मूल के साथ ओवरराइट करता है और कमांड निष्पादित करता है
  5. जब आप सीटीआर-सी दबाते हैं तो खुद के बाद साफ हो जाता है

    #!/bin/sh  
    f=$1  
    shift  
    cmd=$*  
    tmpf="`mktemp /tmp/onchange.XXXXX`"  
    cp "$f" "$tmpf"  
    trap "rm $tmpf; exit 1" 2  
    while : ; do  
        if [ "$f" -nt "$tmpf" ]; then  
            cp "$f" "$tmpf"  
            $cmd  
        fi  
        sleep 2  
    done  
    

यह फ्रीबीएसडी पर काम करता है। एकमात्र पोर्टेबिलिटी समस्या जो मैं सोच सकता हूं वह यह है कि अगर किसी अन्य यूनिक्स में mktemp (1) कमांड नहीं है, लेकिन उस स्थिति में आप temp फ़ाइल नाम को कड़ी मेहनत कर सकते हैं।


12
2017-08-27 21:23



मतदान एकमात्र पोर्टेबल तरीका है, लेकिन अधिकांश प्रणालियों में फ़ाइल परिवर्तन अधिसूचना तंत्र होता है (लिनक्स पर inotify, फ्रीबीएसडी पर kqueue, ...)। जब आप करते हैं तो आपके पास गंभीर उद्धरण समस्या होती है $cmd, लेकिन सौभाग्य से यह आसानी से ठीक करने योग्य है: खिसकाना cmd परिवर्तनीय और निष्पादित करें "$@"। आपकी स्क्रिप्ट एक बड़ी फ़ाइल की निगरानी के लिए उपयुक्त नहीं है, लेकिन इसे प्रतिस्थापित करके तय किया जा सकता है cp द्वारा touch -r (आपको केवल तारीख की आवश्यकता है, सामग्री नहीं)। पोर्टेबिलिटी-वार, द -nt परीक्षण के लिए बैश, केश या जेएसएच की आवश्यकता होती है। - Gilles


उन लोगों के लिए जो स्थापित नहीं कर सकते हैं inotify-tools मेरे जैसे, यह उपयोगी होना चाहिए:

watch -d -t -g ls -lR

जब आउटपुट बदलता है तो यह आदेश बाहर निकल जाएगा, ls -lR प्रत्येक फ़ाइल और निर्देशिका को इसके आकार और तिथियों के साथ सूचीबद्ध करेगा, इसलिए अगर कोई फ़ाइल बदली जाती है तो उसे कमांड से बाहर निकलना चाहिए, जैसा कि मनुष्य कहता है:

-g, --chgexit
          Exit when the output of command changes.

मुझे पता है कि यह जवाब किसी के द्वारा नहीं पढ़ा जा सकता है, लेकिन मुझे आशा है कि कोई इसके पास पहुंच जाएगा।

कमांड लाइन उदाहरण:

~ $ cd /tmp
~ $ watch -d -t -g ls -lR && echo "1,2,3"

एक और टर्मिनल खोलें:

~ $ echo "testing" > /tmp/test

अब पहला टर्मिनल आउटपुट होगा 1,2,3

सरल लिपि उदाहरण:

#!/bin/bash
DIR_TO_WATCH=${1}
COMMAND=${2}

watch -d -t -g ls -lR ${DIR_TO_WATCH} && ${COMMAND}

9
2018-03-22 14:57



अच्छा हैक। मैंने परीक्षण किया और ऐसा लगता है कि लिस्टिंग लंबी है और बदली गई फ़ाइल स्क्रीन के बाहर आती है। एक छोटा संशोधन इस तरह कुछ हो सकता है: watch -d -t -g "ls -lR tmp | sha1sum" - Atle
यदि आप हर सेकेंड में अपना समाधान देखते हैं, तो यह हमेशा के लिए काम करता है और कुछ फ़ाइल बदलता है तो केवल MY_COMMAND चलाएं: watch -n1 "watch -d -t -g ls -lR && MY_COMMAND" - mnesarco
घड़ी का मेरा संस्करण (लिनक्स पर, watch from procps-ng 3.3.10) इसलिए, इसके अंतराल के लिए फ्लोट सेकंड स्वीकार करता है watch -n0.2 ... एक सेकंड के हर पांचवें मतदान करेंगे। उन स्वस्थ उप-मिलीसेकंद इकाई परीक्षणों के लिए अच्छा है। - Jonathan Hartley