GNU/Linux >> Tutoriels Linux >  >> Linux

Quelle est la bonne façon d'utiliser inotify ?

Vous trouverez ci-dessous un extrait de la façon dont vous pouvez utiliser inotify pour regarder "aaa". Notez que je n'ai pas testé cela, je ne l'ai même pas compilé ! Vous devrez y ajouter une vérification des erreurs.

Au lieu d'utiliser une lecture bloquante, vous pouvez également utiliser poll/select sur inotfd.

const char *filename = "aaa";
int inotfd = inotify_init();

int watch_desc = inotify_add_watch(inotfd, filename, IN_MODIFY);

size_t bufsiz = sizeof(struct inotify_event) + PATH_MAX + 1;
struct inotify_event* event = malloc(bufsiz);

/* wait for an event to occur */
read(inotfd, event, bufsiz);

/* process event struct here */

Si tout ce dont vous avez besoin est une application en ligne de commande, il y en a une appelée inotifywait qui surveille les fichiers en utilisant inotify

du terminal 1

# touch cheese
# while inotifywait -e modify cheese; do 
>   echo someone touched my cheese
> done

depuis l'aérogare 2

echo lol >> cheese

voici ce que l'on voit sur le terminal 1

Setting up watches.
Watches established.
cheese MODIFY 
someone touched my cheese
Setting up watches.
Watches established.

Mettre à jour :à utiliser avec prudence et voir les commentaires.


Étant donné que la question initiale semble mentionner Qt en tant que balise, comme indiqué dans plusieurs commentaires ici, les moteurs de recherche peuvent vous avoir conduit ici.

Si quelqu'un veut savoir comment le faire avec Qt, voir http://doc.qt.io/qt-5/qfilesystemwatcher.html pour la version Qt. Sous Linux, il utilise un sous-ensemble d'Inotify, s'il est disponible, voir l'explication sur la page Qt pour plus de détails.

En gros, le code nécessaire ressemble à ceci :

dans mainwindow.h ajouter :

QFileSystemWatcher * watcher;
private slots:
    void directoryChanged(const QString & path);
    void fileChanged(const QString & path);

et pour mainwindow.cpp :

#include <QFileInfo>
#include <QFileSystemWatcher>

watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &)));
connect(watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
watcher->addPath("/tmp/"); // watch directory
watcher->addPath("/tmp/a.file");  // watch file

ajoutez également les slots dans mainwindow.cpp qui sont appelés si un changement de fichier/répertoire est remarqué :

void MainWindow::directoryChanged(const QString & path) {
     qDebug() << path;
}
void MainWindow::fileChanged(const QString & path) {
     qDebug() << path;
}

  • Documentation (à partir de Surveiller l'activité du système de fichiers dansnotify)

Le inotify API C

inotify fournit trois appels système pour créer des moniteurs de système de fichiers de toutes sortes :

  • inotify_init() crée une instance du inotify sous-système dans le noyau et renvoie un descripteur de fichier en cas de succès et -1 en cas d'échec. Comme les autres appels système, si inotify_init() échoue, vérifiez errno pour les diagnostics.
  • inotify_add_watch() , comme son nom l'indique, ajoute une montre . Chaque montre doit fournir un chemin d'accès et une liste d'événements pertinents, où chaque événement est spécifié par une constante, telle que IN_MODIFY . Pour surveiller plus d'un événement, utilisez simplement l'opérateur logique ou — l'opérateur pipe (|) en C — entre chaque événement. Si inotify_add_watch() réussit, l'appel renvoie un identifiant unique pour la montre enregistrée ; sinon, il renvoie -1 . Utilisez l'identifiant pour modifier ou supprimer la montre associée.
  • inotify_rm_watch() supprime une montre.

Le read() et close() des appels système sont également nécessaires. Étant donné le descripteur généré par inotify_init() , appelez le read() attendre les alertes. En supposant un descripteur de fichier typique, l'application bloque en attendant la réception d'événements, qui sont exprimés sous forme de données dans le flux. Le close() commun sur le descripteur de fichier généré à partir de inotify_init() supprime et libère toutes les veilles actives ainsi que toute la mémoire associée à l'instance inotify. (La mise en garde typique du nombre de références s'applique ici aussi. Tous les descripteurs de fichiers associés à une instance doivent être fermés avant que la mémoire consommée par les montres et par inotify ne soit libérée.)

  • Un exemple (de Kernel Korner - Intro to inotify)
#include "inotify.h"  
#include "inotify-syscalls.h"  
int wd;   
wd = inotify_add_watch (fd,   
            "/home/rlove/Desktop", IN_MODIFY | IN_CREATE | IN_DELETE);
if (wd < 0)
      perror ("inotify_add_watch");

Cet exemple ajoute une veille sur le répertoire /home/rlove/Desktop pour toute modification, création de fichier ou suppression de fichier.


Linux
  1. Comment utiliser la commande Tar sous Linux

  2. Quel est le but du fichier .bashrc sous Linux

  3. À quoi sert $# dans Bash

  4. Quelle est la meilleure façon d'apprendre SELinux ?

  5. Existe-t-il un moyen approprié d'effacer les journaux ?

Comment utiliser la commande touch sous Linux

Comment utiliser la commande Linux head

Comment utiliser la commande Linux diff

Comment utiliser la commande Gzip sous Linux ?

À quoi sert LLVM dans les chaînes d'outils Android NDK ?

Quel est le moyen le plus rapide d'exécuter un script ?