GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cuál es la forma correcta de usar inotify?

A continuación se muestra un fragmento de cómo puede usar inotify para ver "aaa". Tenga en cuenta que no he probado esto, ¡ni siquiera lo he compilado! Deberá agregarle una verificación de errores.

En lugar de usar una lectura de bloqueo, también puede usar poll/select en 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 todo lo que necesita es una aplicación de línea de comandos, hay una llamada inotifywait que mira archivos usando inotify

desde la terminal 1

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

desde la terminal 2

echo lol >> cheese

esto es lo que se ve en la terminal 1

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

Actualizar :usar con precaución y ver los comentarios.


Dado que la pregunta inicial parece mencionar a Qt como una etiqueta, como se indica en varios comentarios aquí, es posible que los motores de búsqueda lo hayan conducido aquí.

Si alguien quiere saber cómo hacerlo con Qt, vea http://doc.qt.io/qt-5/qfilesystemwatcher.html para la versión de Qt. En Linux, usa un subconjunto de Inotify, si está disponible, consulte la explicación en la página de Qt para obtener más detalles.

Básicamente, el código necesario se ve así:

en mainwindow.h agregar:

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

y para ventana principal.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

también agregue las ranuras en mainwindow.cpp que se llaman si se nota un cambio de archivo/directorio:

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

  • Documentación (de Supervisar la actividad del sistema de archivos dentro denotify)

El inotify API de C

inotify proporciona tres llamadas al sistema para crear monitores de sistemas de archivos de todo tipo:

  • inotify_init() crea una instancia del inotify subsistema en el núcleo y devuelve un descriptor de archivo en caso de éxito y -1 sobre el fracaso Al igual que otras llamadas al sistema, si inotify_init() falla, marque errno para el diagnóstico.
  • inotify_add_watch() , como su nombre lo indica, agrega un reloj . Cada reloj debe proporcionar un nombre de ruta y una lista de eventos pertinentes, donde cada evento se especifica mediante una constante, como IN_MODIFY . Para monitorear más de un evento, simplemente use el operador lógico o —el operador de barra vertical (|) en C—entre cada evento. Si inotify_add_watch() tiene éxito, la llamada devuelve un identificador único para el reloj registrado; de lo contrario, devuelve -1 . Utilice el identificador para modificar o eliminar el reloj asociado.
  • inotify_rm_watch() quita un reloj.

El read() y close() También se necesitan llamadas al sistema. Dado el descriptor producido por inotify_init() , llama al read() a esperar alertas. Suponiendo un descriptor de archivo típico, la aplicación se bloquea en espera de la recepción de eventos, que se expresan como datos en el flujo. El cierre común () en el descriptor de archivo producido a partir de inotify_init() elimina y libera todos los relojes activos, así como toda la memoria asociada con la instancia de inotify. (Aquí también se aplica la típica advertencia de recuento de referencias. Todos los descriptores de archivo asociados con una instancia deben cerrarse antes de que se libere la memoria consumida por los relojes y por inotify).

  • Un ejemplo (de Kernel Korner - Introducción a 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");

Este ejemplo agrega una vigilancia en el directorio /home/rlove/Desktop para cualquier modificación, creación o eliminación de archivos.


Linux
  1. ¿Cómo uso las líneas de un archivo como argumentos de un comando?

  2. ¿Cuál es la forma correcta de insertar una pestaña en sed?

  3. ¿Cuál es el uso de $# en Bash?

  4. ¿Qué significa el 'rc' en '.bashrc', etc.?

  5. ¿Cuál es la mejor manera de aprender SELinux?

Cómo usar el comando táctil en Linux

Cómo usar el comando de cabeza de Linux

Cómo usar el comando diff de Linux

¿Cómo usar el comando Gzip en Linux?

¿Cuál es el uso de LLVM en las cadenas de herramientas de Android NDK?

¿Cuál es la forma más rápida de ejecutar un script?