GNU/Linux >> Linux Esercitazione >  >> Linux

Qual è il modo corretto di usare inotify?

Di seguito è riportato uno snippet di come utilizzare inotify per guardare "aaa". Nota che non l'ho testato, non l'ho nemmeno compilato! Dovrai aggiungere il controllo degli errori.

Invece di usare una lettura bloccante puoi anche usare poll/select su 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 */

Se tutto ciò di cui hai bisogno è un'applicazione a riga di comando, ce n'è una chiamata inotifywait che controlla i file usando inotify

dal terminale 1

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

dal terminal 2

echo lol >> cheese

ecco cosa si vede sul terminale 1

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

Aggiorna :usare con cautela e vedere i commenti.


Poiché la domanda iniziale sembra menzionare Qt come tag, come indicato in diversi commenti qui, i motori di ricerca potrebbero averti portato qui.

Se qualcuno vuole sapere come farlo con Qt, vedere http://doc.qt.io/qt-5/qfilesystemwatcher.html per la versione Qt. Su Linux utilizza un sottoinsieme di Inotify, se disponibile, vedere la spiegazione nella pagina Qt per i dettagli.

Fondamentalmente il codice necessario è simile a questo:

in mainwindow.h aggiungi :

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

e per 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

aggiungi anche gli slot in mainwindow.cpp che vengono chiamati se viene notato un cambio di file/directory:

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

  • Documentazione (da Monitora l'attività del file system all'interno di notifica)

Il inotify API C

inotify fornisce tre chiamate di sistema per creare monitor di file system di tutti i tipi:

  • inotify_init() crea un'istanza del inotify sottosistema nel kernel e restituisce un descrittore di file in caso di successo e -1 in caso di fallimento. Come altre chiamate di sistema, se inotify_init() fallisce, seleziona errno per la diagnostica.
  • inotify_add_watch() , come suggerisce il nome, aggiunge un orologio . Ogni controllo deve fornire un percorso e un elenco di eventi pertinenti, in cui ogni evento è specificato da una costante, ad esempio IN_MODIFY . Per monitorare più di un evento, usa semplicemente l'operatore logico or — l'operatore pipe (|) in C — tra ogni evento. Se inotify_add_watch() ha esito positivo, la chiamata restituisce un identificatore univoco per l'orologio registrato; in caso contrario, restituisce -1 . Utilizza l'identificatore per modificare o rimuovere l'orologio associato.
  • inotify_rm_watch() rimuove un orologio.

Il read() e close() sono necessarie anche le chiamate di sistema. Dato il descrittore prodotto da inotify_init() , chiama read() per attendere gli avvisi. Assumendo un tipico descrittore di file, l'applicazione si blocca in attesa della ricezione di eventi, che sono espressi come dati nel flusso. Il comune close() sul descrittore di file prodotto da inotify_init() cancella e libera tutti i watch attivi così come tutta la memoria associata all'istanza inotify. (Anche qui si applica il tipico avvertimento relativo al conteggio dei riferimenti. Tutti i descrittori di file associati a un'istanza devono essere chiusi prima che la memoria consumata dai watch e da inotify venga liberata.)

  • Un esempio (da 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");

Questo esempio aggiunge un controllo sulla directory /home/rlove/Desktop per qualsiasi modifica, creazione o eliminazione di file.


Linux
  1. Qual è lo scopo del file .bashrc in Linux

  2. Come utilizzo le righe di un file come argomenti di un comando?

  3. Cosa significa 'rc' in `.bashrc`, ecc.?

  4. Qual è il modo migliore per imparare SELinux?

  5. Modo corretto di utilizzare OnFailure in systemd

Come utilizzare il comando touch in Linux

Come utilizzare il comando head di Linux

Come usare il comando diff di Linux

Come utilizzare il comando Gzip in Linux?

Qual è l'uso di LLVM nelle toolchain Android NDK?

Qual è il modo più veloce per eseguire uno script?