web-dev-qa-db-fra.com

inotify et bash

J'essaie de créer un script bash avec inotify-tools qui surveillera un répertoire et modifiera tous les nouveaux fichiers en supprimant les lignes contenant "EE". Une fois modifié, il déplacera les fichiers vers un autre répertoire

    #!/bin/sh
    while inotifywait -e create /home/inventory/initcsv; do
      sed '/^\"EE/d' Filein > fileout #how to capture File name?
      mv fileout /home/inventory/csvstorage
    fi
    done

Veuillez aider?

25
user963091

Par défaut, la sortie texte de inotifywait -e CREATE Est de forme

     watched_filename CREATE event_filename

watched_filename représente /home/inventory/initcsv et event_filename représente le nom du nouveau fichier.

Donc, à la place de votre ligne while inotifywait -e ..., Mettez:

    DIR=/home/inventory/initcsv
    while RES=$(inotifywait -e create $DIR); do
        F=${RES#?*CREATE }

et dans votre ligne sed, utilisez $F comme nom Filein. Notez que la construction $(...) est une forme de substitution de processus compatible avec Posix (souvent effectuée à l'aide de contre-coups) et le résultat ${RES#pattern} Est égal à $RES Avec le préfixe de correspondance de motif le plus court supprimé. Notez que le dernier caractère du motif est un blanc. [Voir mise à jour 2]

Mise à jour 1 Pour gérer les noms de fichiers qui peuvent contenir des espaces, utilisez dans la ligne sed "$F" Au lieu de $F. Autrement dit, utilisez des guillemets doubles autour de la référence à la valeur de F.

Les définitions RES=... Et F=... N'ont pas besoin d'utiliser des guillemets doubles, mais vous pouvez les utiliser si vous le souhaitez; par exemple: F=${RES#?*CREATE } et F="${RES#?*CREATE }" fonctionneront tous les deux correctement lors de la gestion des noms de fichiers contenant des espaces.

Mise à jour 2 Comme indiqué dans le commentaire de Daan, inotifywait a un paramètre --format Qui contrôle la forme de sa sortie. Avec commande

while RES=$(inotifywait -e create $DIR --format %f .)
   do echo RES is $RES at `date`; done

s'exécutant dans un terminal et une commande

touch a aa; sleep 1; touch aaa;sleep 1; touch aaaa

fonctionnant dans un autre terminal, la sortie suivante est apparue dans le premier terminal:

Setting up watches.
Watches established.
RES is a at Tue Dec 31 11:37:20 MST 2013
Setting up watches.
Watches established.
RES is aaa at Tue Dec 31 11:37:21 MST 2013
Setting up watches.
Watches established.
RES is aaaa at Tue Dec 31 11:37:22 MST 2013
Setting up watches.
Watches established.
22

La sortie de inotifywait est de la forme:

filename eventlist [eventfilename]

Si vos noms de fichiers peuvent contenir des espaces et des virgules, cela devient difficile à analyser. S'il ne contient que des noms de fichiers `` sains '', vous pouvez faire:

srcdir=/home/inventory/initcsv
tgtdir=/home/inventory/csvstorage
inotifywait -m -e create "$directory" |
while read filename eventlist eventfile
do
    sed '/^"EE/d'/' "$srcdir/$eventfile" > "$tgtdir/$eventfile" &&
    rm -f "$srcdir/$eventfile
done
12
Jonathan Leffler

Citant la page de manuel d'inotifywait:

inotifywait will output diagnostic information on standard error and event information  on
   standard  output.  The event output can be configured, but by default it consists of lines
   of the following form:

   watched_filename EVENT_NAMES event_filename

   watched_filename
          is the name of the file on which the event occurred.  If the file is a directory, a
          trailing slash is output.

En d'autres termes, il imprime les noms des fichiers sur la sortie standard. Vous devez donc les lire à partir de la sortie standard et les utiliser pour faire ce que vous voulez faire.

1
bmargulies