Αυτοματισμοί με το incron

Με το incron μπορούμε να δούμε αλλαγές σε ένα φάκελο στο σύστημα αρχείων και να εκτελέσουμε εντολές αυτόματα μόλις αυτές συμβούν. Για παράδειγμα έστω ότι τρέχετε ένα πρόγραμμα που κάνει υπολογισμούς που θα κάνουν ώρες να ολοκληρωθούν. Μόλις τελειώσουν αυτόματα να σας έρθει το αποτέλεσμα με ένα email.

Το όνομα incron δηλώνει μια στενή σχέση με το γνωστό cron για εκτέλεση εργασιών σε τακτά χρονικά διαστήματα. Αλλά κάνουν διαφορετικά πράγματα και μόνο μια μικρή ομοιότητα υπάρχει με το αρχείο ενεργειών.

Εγκατάσταση

Θα πρέπει να εγκαταστήσουμε το πακέτο ανάλογα με την διανομή μας. Σε διανομές βασισμένες στο Debian :debian: όπως Ubuntu :ubuntu: ή :mint:

 apt install incron

Μετά την εγκατάσταση θα πρέπει να ελέγξουμε αν η σχετική υπηρεσία τρέχει και αν όχι να την ενεργοποιήσουμε.

 systemctl status --no-pager incron.service

Στην συνέχεια θα πρέπει να ορίσουμε ποιος επιτρέπετε να χρησιμοποιεί την υπηρεσία και ποιος όχι. Αυτό το καθορίζουν δυο αρχεία

/etc/incron.allow
/etc/incron.deny

Θα πρέπει να ανοίξεις το αρχείο /etc/incron.allow και να προσθέσεις τους χρήστες που θέλεις να το χρησιμοποιούν. Προσωπικά διάλεξα τον εύκολο δρόμο και απλά έσβησα αυτό το αρχείο. Έτσι μόνο το άλλο αρχείο που απαγορεύει σε συγκεκριμένους χρήστες την υπηρεσία θα είναι ενεργό.

sudo rm /etc/incron.allow

Με το τρόπο αυτό όμως θα μπορεί να τρέχει ενέργειες και ο χρήστης root, οπότε προσοχή. Αν όλα πήγαν καλά θα μπορώ να δω ποιες ενέργειες τρέχω με την εντολή

incrontab --list       (ή απλά -l)

Προαιρετικά μπορώ να ρυθμίσω τον διορθωτή που θα χρησιμοποιεί προσθέτοντας μια γραμμή σαν την παρακάτω στο αρχείο /etc/incron.conf

editor = gedit

όπου αντί για gedit θα βάλω αυτόν που χρησιμοποιώ (xed, pluma, kate, gvim, …) .

Χρήση

Πλέον μπορούμε να προσθέσουμε εργασίες με την εντολή

incrontab --edit

Η δομή μοπιάζει πολύ με το απλό cron. Για κάθε κατάλογο η αρχείο που θέλουμε να παρακολουθήσουμε θα προσθέσουμε μια γραμμή σαν την παρακάτω

<ΦΑΚΕΛΛΟΣ>                <ΜΑΣΚΑ>             <ΕΝΤΟΛΗ>
/home/mitsos/timologia   IN_MODIFY,IN_NO_LOOP //home/mitsos/bin/sync.sh

Δηλαδή ένα όνομα φακέλου, μια σειρά απο πράγματα (γεγονότα) που θα κοιτάξει και μια εντολή που θα εκτελεστεί. Η εντολή μπορεί να είναι και κάποιο script που έχουμε φτιάξει.

Ο παρακάτω πίνακας δείχνει τα γεγονότα που υπάρχουν

Event Meaning
Common Events
IN_ACCESS File was accessed (read)
IN_ATTRIB Metadata was changed (permissions, timestamps, extended attributes, etc.)
IN_CLOSE_WRITE File opened for writing was closed
IN_CLOSE_NOWRITE File not opened for writing was closed
IN_CLOSE Combines IN_CLOSE_WRITE and IN_CLOSE_NOWRITE
IN_CREATE File/directory created in watched directory
IN_DELETE File/directory deleted from watched directory
IN_DELETE_SELF Watched file/directory was deleted
IN_MODIFY File was modified
IN_MOVE_SELF Watched file/directory was moved
IN_MOVED_FROM File moved out of watched directory
IN_MOVED_TO File moved into watched directory
IN_MOVE A combination of IN_MOVED_FROM and IN_MOVED_TO .
IN_OPEN File was opened
Special Events
IN_ALL_EVENTS Combines all of the above events
IN_DONT_FOLLOW Don’t dereference pathname if it is a symbolic link
IN_ONESHOT Monitor pathname for only one event
IN_ONLYDIR Only watch pathname if it is a directory
Wildcard Event
IN_NO_LOOP Disable monitoring of events until the current event is handled completely (until its child process exits – avoids infinite loops)

Ενώ μπορούμε να δώσουμε επιπλέον πληροφορίες στο πρόγραμμα για το αρχείο και τον κατάλογο που έγινε το γεγονός

Wildcard Meaning
$@ Watched filesystem path
$# Event-related file name
$% Event flag (textual)

Επειδή τα παρακάτω ίσως μοιάζουν με κινέζικα (Μανδαρίνικα) ας το δούμε σε ένα απλό παράδειγμα σε Καντονέζικα. Πρώτα θα φτιάξω ένα απλό πρόγραμμα που απλά θα τυπώνει τις παραμέτρους του σε ένα αρχείο (που θα παρακολουθώ σε ένα τερματικό με την εντολή touch ~/_actions_log.txt && tail -f ~/_actions_log.txt Το αρχείο θα το βάλω στον φάκελο ${HOME}/.local/bin/` και θα έχει όνομα debug_inotify.sh. Θα περιέχει το παρακάτω

#!/bin/bash
echo "Path: '$1', filename '$2',  actions '$3'" >> ~/_actions_log.txt 

Θα προσθέσω τον παρακάτω κανόνα

/home/mitsos/tmp IN_ALL_EVENTS /home/mistos/.local/bin/debug_inotify.sh $@ $# $%

πειράζοντας τα αρχεία στον φάκελο θα βλέπω τι συμβαίνει. Πολλές φορές αυτό που πραγματικά συμβαίνει είναι άλλο από αυτό που νομίζεις. Συχνά για παράδειγμα νομίζεις πως αλλάζεις ένα αρχείο, αλλά για να μην πάει κάτι στραβά το πρόγραμμα φτιάχνει πρώτα ένα άλλο αρχείο, σβήνει το αρχικό και μετά αλλάζει όνομα στο καινούργιο. Με τον τρόπο αυτό θα καταλάβεις και ποια γεγονότα σε ενδιαφέρουν για το σενάριο που θέλεις να υλοποιήσεις.

Προβλήματα

Δεν έχω βρει κάποιο γραφικό περιβάλλον που να απλοποιεί τη χρήση του, αν και πιστεύω πως αυτό θα έπρεπε κανονικά να είναι μια ενσωματωμένη λειτουργία του διαχειριστή αρχείων. Αλλά ζούμε στον κόσμο του Linux και αυτό δεν θα πρέπει να είναι πρόβλημα. Σωστά; :smile:

Το μεγάλο πρόβλημα που έχω βρει είναι πως δεν υποστηρίζει υποκατάλογους. Θα δει μόνο ένα κατάλογο. Υπάρχουν δυο project που προσπαθούν να λύσουν το πρόβλημα. Το ένα είναι το watcher που χρησιμοποιεί αρχεία YAML και ένας κλώνος του με το ίδιο όνομα :angry: που χρησιμοποιεί αρχεία INI.

Χρήσεις

Οι χρήσεις εξαρτιόνται από την φαντασία σου

  • Μπορείς να παρακολουθείς ενα αρχείο \LaTeX{} ή κάποιο κώδικα και να τον κάνει compile αμέσως μόλις σώσεις ένα αρχείο.
  • Μπορείς να στέλνεις με email αρχεία που προσθέτεις σε ένα φάκελο, ή να τα τυπώνεις σε ένα εκτυπωτή ή να κάνεις αντίγραφο σε ένα απομακρυσμένο δίσκο
  • Να επανεκκινεί μια υπηρεσία αν αλλάξεις τα αρχεία ρυθμίσεων της
  • Να κάνεις επεξεργασίες στις φωτογραφίες ενός καταλόγου
  • Ένα γρήγορο τρόπο να κάνεις trigger πράγματα κάνοντας touch ένα αρχείο
  • Να βαρέσει συναγερμός αν κάποιος πάει να δει τον φάκελο με τις τσό απόρρητα αρχεία.

Αν το βρήκατε χρήσιμο μοιραστείτε μαζί μας το πως το χρησιμοποιήσατε.

6 Likes

σκεφτομαι αν με βοηθησει καποιος στο σκριπτιγκ (αν δεν μπορεσω μονος μου) να στελνω τις φωτογραφιες που τραβαει η timelapse καμερα που εχω φτιαξει με ενα raspberry pi zero w, στον υπολογιστη οχι με mail ομως (μεσω ftp ισως; )

Η καλύτερη λύση είναι να στέλνεις το αρχείο με ssh. Οδηγίες να φτιάξεις κλειδιά και να το κάνεις υπάρχουν παντού. Αν έχεις στήσει τα κλειδιά, κάπως έτσι (αδοκίμαστο)

scp "$@/$#" remote_username@rasp_ip:/remote/directory
1 Like

για καποιο λογο που δεν γνωριζω, δυο φορες που δοκιμασα με αυτο τον τροπο δε μου δουλεψε. Δε δουλεψαν οι εντολες cp και scp δηλαδη. Ομως το δοκιμασα με termux απο το κινητο, ισως πρεπει να δω αν αλλάζει κατι απο τον υπολογιστη…
θενξ παντως…
edit
με filezilla παντως μια χαρα γινεται η δουλεια… απλα με λιγο αυτοματισμο θα ηταν καλλιτερα

και η εντολη entr μπορει να χρησιμοποιηθει με παρομοιο τροπο απο οτι καταλαβαινω. ναι;

Πίσω από όλα αυτά είναι κάποιες κλήσεις συστήματος του linux kernel. Ένα πρόγραμμα κάνει αίτηση στον πυρήνα και ζητά να ενημερώνετε αν κάτι αλλάξει και στην συνέχεια αντιδρά ανάλογα.

Η διαφορά είναι πως το entr η το ποιο γνωστό inotify-wait είναι προγράμματα που πρέπει να τα τρέχεις σε ένα τερματικό, αν και όποτε τα χρειαστείς.

Το incron λειτουργεί σαν μια υπηρεσία συστήματος. Δηλαδή θα τρέχει πάντα από την στιγμή που θα ξεκινήσει ο υπολογιστής μέχρι να τον κλείσεις, χωρίς να κάνεις απολύτως τίποτα.

Οπότε κάθε τι έχει την χρήση του. Αλλά θα επιλέξω το incron για σχεδόν όλλες τις χρήσεις, γιατί δεν είναι οτι ποιο εύκολο να τα δουλέψεις από γραμμή εντολών. Το entr είναι απλούστερο, αλλά μπαίνω στην σελίδα και βλέπω το πρώτο παράδειγμα

ls | entr make

και αμέσως βλέπω πως αυτό είναι λάθος στην γενική περίπτωση. Βλέπει κανένας το γιατί; Παρακάτω βλέπω πως μια σωστότερη λύση θα ήταν κάπως έτσι (μια πλήρης λύση θα έπρεπε να βλέπει σε υποκαταλόγους, όπου όμως πάσχει και το incron όποτε κάνω την :duck:).

while true; do
   ls | entr -d make
done

Όχι τόσο απλό πλέον.

1 Like

μια απορια πανω σε αυτο →

στο τεταρτο παραδειγμα που εχει στη man page του entr λεει →

Rebuild project if a source file is modified or added to the src/ directory:
$ while true; do ls src/*.rb | entr -d make; done

δηλαδη εκει που γραφει src/* δε σημαινει οτι βλεπει και υποκαταλογους;

Όχι, αυτό βλέπει ένα επίπεδο καταλόγου. Δεν βλέπει υποκατάλογους. Μια καταληλότερη εντολή θα ήταν η find. Επίσης βλέπω ένα δεύτερο, αν και ελάσσονα πρόβλημα, δεν υπάρχει κάποια μνήμη στην εντολή και η αρχικοποίηση των καταλόγων θα γίνει κάθε φορά από την αρχή. Κάνει μεν την σύνταξη ευκολότερη σε σχέση με την inotify-wait μεν, αλλά στην περίπτωση που έχεις μερικές δεκάδες χιλιάδες αρχείων θα πονέσει άσχημα :crazy_face:

1 Like