inotify è un sottosistema del kernel di Linux che agisce per estendere le funzionalità del filesystem per notare dei cambiamenti nel filesystem, e segnalare le modifiche alle applicazioni. Esso sostituisce il precedente, dnotify, che aveva obiettivi simili.
Gli sviluppatori originali di inotify furono John McCutchan, Robert Love e Amy Griffis. E’ stato incluso nel kernel Linux dalla versione 2.6.13 (18 giugno 2005), e poteva essere compilato nel 2.6.12 e, eventualmente, in versioni precedenti con l’uso di una patch.
Un utilizzo è nel settore dei servizi di ricerca da desktop come Beagle, dove la sua funzionalità permette la reindicizzazione dei file modificati, senza dover eseguire la scansione del file system per cercare modifiche ogni pochi minuti, il che sarebbe molto inefficiente. Essendo informato che un file è stato modificato direttamente dal kernel, piuttosto che cercando attivamente, Beagle e strumenti simili possono ottenere tempi di cambio e reindicizazzione di solo circa un secondo.
Può anche essere utilizzato per aggiornare automaticamente le viste delle directory, ricaricare i file di configurazione, i cambiamenti nei file di log, fare backup, sincronizzare o upload.
Esempi nella Shell
Per utilizzare la potenza di inotify è necessario installare il pacchetto inotify-tools (disponibile per tutte le principali distribuzioni), dopo di che è possibile utilizzare il comando “inotifywait”, una funzione che lo rende facile da integrare con il script di shell.
inotifywait
Questo comando semplicemente si blocca in attesa di eventi da inotify , il che lo rende appropriato per l’uso in script di shell. E’ possibile guardare qualsiasi insieme di file e directory, e può ricorsivamente guardare interi alberi di directory.
Esempio 1
#!/bin/sh
# get the current path
CURPATH=`pwd`
inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f'
-e close_write /tmp/test | while read date time dir file; do
FILECHANGE=${dir}${file}
# convert absolute path to relative
FILECHANGEREL=`echo "$FILECHANGE" | sed 's_'$CURPATH'/__'`
rsync --progress --relative -vrae 'ssh -p 22' $FILECHANGEREL [email protected]:/backup/root/dir &&
echo "At ${time} on ${date}, file $FILECHANGE was backed up via rsync"
done
In questo esempio controlliamo /tmp/test e se un evento di “close_write” e’ colto allora eseguiamo uni rsync di quel file in una posizione remota.
Esempio 2
Considerate il semplice esempio di voler monitorare la directory /tmp e stampare un messaggio ogni votla che un file viene aggiunto.
#!/bin/sh
# CONFIGURATION
DIR="/tmp"
EVENTS="create"
FIFO="/tmp/inotify2.fifo"
# FUNCTIONS
on_exit() {
kill $INOTIFY_PID
rm $FIFO
exit
}
on_event() {
local date=$1
local time=$2
local file=$3
sleep 5
echo "$date $time Fichier créé: $file"
}
# MAIN
if [ ! -e "$FIFO" ]
then
mkfifo "$FIFO"
fi
inotifywait -m -e "$EVENTS" --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %f' "$DIR" > "$FIFO" &
INOTIFY_PID=$!
trap "on_exit" 2 3 15
while read date time file
do
on_event $date $time $file &
done < "$FIFO"
on_exit
Dettagli:
- La funzione on_event viene lanciata in background (un sub-processo di shell è effettivamente creato)
- Le operazioni sono eseguite in elaborazione parallela pratico per multi-processori
- Con l’uso della named pipe $FIFO è possibile eseguire il comando inotifywait in background ed ottenere il suo PID
- E ‘ possibile installare una “trap”, cioè la on_exit function () “, che uccide il comando inotifywait (ed elimina la named pipe) quando lo script è ucciso con i segnali 2 (INT ), 3 (QUIT) or 15 (TERM)
- Gli eventi vengono effettuati attraverso la named pipe, senza creare una shell, attraverso la fine del “while” done <$ FIFO
Stai “inotified”
Ci sono molte utilità basate su inotify da considerare in aggiunta al vostro bagaglio di trucchi. L’utilità incron è un corollario di cron, ma reagisce agli eventi inotify invece di una pianificazione temporale. L’utilità inoticoming è specificamente progettato per monitorare dropboxes. E se sei uno sviluppatore Perl, Ruby, Python o, si possono trovare moduli e librerie per chiamare inotify dalla comodità della vostra lingua preferita di scripting.
Per esempio, per i programmatori Perl è possibile utilizzare Linux:: Inotify2 per incorporare le funzionalità di inotify in qualsiasi applicazione Perl.
Questo codice, preso dalla Linux:: file README Inotify2, mostra un’interfaccia di callback per monitorare gli eventi su filesystem:
use Linux::Inotify2;
my $inotify = new Linux::Inotify2
or die "Unable to create new inotify object: $!";
# for Event:
Event->io (fd =>$inotify->fileno, poll => 'r', cb => sub { $inotify->poll });
# for Glib:
add_watch Glib::IO $inotify->fileno, in => sub { $inotify->poll };
# manually:
1 while $inotify->poll;
# add watchers
$inotify->watch ("/etc/passwd", IN_ACCESS, sub {
my $e = shift;
my $name = $e->fullname;
print "$name was accessedn" if $e->IN_ACCESS;
print "$name is no longer mountedn" if $e->IN_UNMOUNT;
print "$name is gonen" if $e->IN_IGNORED;
print "events for $name have been lostn" if $e->IN_Q_OVERFLOW;
# cancel this watcher: remove no further events
$e->w->cancel;
});
Riferimenti:
http://kerlinux.org/2010/08/utilisation-de-inotifywait-dans-des-scripts-shell/
http://www.ibm.com/developerworks/linux/library/l-ubuntu-inotify/index.html?ca=drs-
Popular Posts:
- None Found
[…] Introducción a inotify http://www.linuxaria.com/article/introduction-inotify?lang=en por algui91 hace 5 segundos […]
I tried out inotify-tools with Example 1 edited to just /tmp folder, but got an Error when running my inotify-tools Example 1 Script…
[don@fedora13gt5408 Shell Scripts]$ ./inotify-tools-Example-1-edited-to-just-tmp-folder.sh
Setting up watches. Beware: since -r was given, this may take a while!
Failed to watch /tmp/; upper limit on inotify watches reached!
Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches’.
[don@fedora13gt5408 Shell Scripts]$
Max is already set to 8192. Tired to 9000 in Kursader root mode, to see if it works. Couldn’t save copy or edit at all, even by starting kwrite and gedit from root Terminal. I wonder if this is an SElinux issue. But I didn’t get any SELinux notices and I have mine set to Permissive mode…
Don
Hello Don,
Just re-tested on my ubunto 10.10, and example 1 seem to work fine here.
I’ve just changed from a rsync to a cp and when i use the program i get:
root@laptop:~# bash test-inotify.sh
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
At 09:39 on 06/12/10, file /tmp/test-two was created and copied in /root/test
At 09:39 on 06/12/10, file /tmp/test-three was created and copied in /root/test
From another terminal i did a touch /tmp/test-two and touch /tmp/test-three.
I tested it with root and a normal account and both worked fine.
Also in Ubuntu /proc/sys/fs/inotify/max_user_watches is set to 8192.
This work on your box ?
root@laptop:~# echo 32000 > /proc/sys/fs/inotify/max_user_watches
root@aptop:~# cat /proc/sys/fs/inotify/max_user_watches
32000
Thanks for the feedback, i usually don’t work with SElinux over time I’ve seen that gives me more problems than it solves.
[…] Introduction to inotify […]
how this inotify script run at background? because when I exit/ log out from the server it stop working 🙂
Check this article: http://linuxaria.com/article/how-to-run-commands-background-nohup-disown?lang=en
The task 4 in particular 😉
For exemple 2, if I want to change the event: modify, he will give me an infinite list of modified files, as soon as I open the directory. How can I fixe that?
Hi, if anyone is able to give me some pointers on why the code below generates an infinite number of rsync actions I would very much appreciate it. I suppose that either I have an infinite loop in my bash script (I’ll confess I’m fresh to bash scripting) or I’m getting an infinite number of notifications from inotify. However, apart from having to add a backslash to a couple of lines to get the code working at all (I’m guessing that those lines may have been split automatically by the page formatting in the example above) it does seem to me that my extract is materially the same as the first example.
#!/bin/sh
inotifywait -m –timefmt ‘%d/%m/%y %H:%M’ –format ‘%T %w %f’ \
-e modify /home/user/apps/db_backups/db_files/ | while read date time dir file; do
FILECHANGE=${dir}${file}
rsync –progress -rlptD -e “ssh -i /home/deploy/.ssh/id_rsa” $FILECHANGE user@server:/home/user/apps/db_backups/db_files && \
echo “At ${time} on ${date}, file $FILECHANGE was backed up via rsync”
done