Vérifier constamment si le fichier est modifié bash


8

J'ai un fichier appelé file1 que je veux dans un script, chaque fois qu'il y a un changement, faites quelque chose, un bip en fait. Comment je fais ça?

Réponses:


14

Si vous avez inotify-toolsinstallé (du moins c'est le nom du paquet sur Debian) quand vous pouvez faire quelque chose comme ceci:

while inotifywait -q -e modify filename >/dev/null; do
    echo "filename is changed"
    # do whatever else you need to do
done

Cela attend que l'événement "modifier" arrive au fichier nommé "nom de fichier". Lorsque cela se produit, la inotifywaitcommande sort filename MODIFY(que nous rejetons en envoyant la sortie à / dev / null) puis se termine, ce qui entraîne la saisie du corps de la boucle.

Lisez la page de manuel inotifywaitpour plus de possibilités.


Bon point, je n'avais pas bien lu la page de
manuel

Vous n'en avez pas strictement besoin while. Notez également que ce qu'un humain considère comme une "modification" peut ne pas toujours fonctionner: cela interceptera un ajout par exemple, mais il n'attrapera pas un éditeur tel que vim(le fichier regardé est renommé ou échangé avec une sauvegarde), ni perl -i(sur place) edit) qui remplace le fichier par un nouveau. Une fois que l'un de ces événements se produit, inotifywaitil ne reviendra jamais. Regarder un inode et regarder un nom de fichier ne sont pas tout à fait la même chose, donc cela dépend du cas d'utilisation.
mr.spuratic

1
Vous pouvez ajouter d'autres événements à attendre, par exemple move_selfles captures seront renommées. Voir la page de manuel pour la liste complète des événements.
wurtel

2

Sans inotifywait, vous pouvez utiliser ce petit script et un travail cron (toutes les minutes environ):

#!/usr/bin/env bash
#
# Provides      : Check if a file is changed
# 
# Limitations   : none
# Options       : none
# Requirements  : bash, md5sum, cut
# 
# Modified      : 11|07|2014
# Author        : ItsMe
# Reply to      : n/a in public
#
# Editor        : joe
#
#####################################
#
# OK - lets work
#

# what file do we want to monitor?
# I did not include commandline options
# but its easy to catch a command line option
# and replace the defaul given here
file=/foo/bar/nattebums/bla.txt

# path to file's saved md5sum
# I did not spend much effort in naming this file
# if you ahve to test multiple files
# so just use a commandline option and use the given
# file name like: filename=$(basename "$file")
fingerprintfile=/tmp/.bla.md5savefile

# does the file exist?
if [ ! -f $file ]
    then
        echo "ERROR: $file does not exist - aborting"
    exit 1
fi

# create the md5sum from the file to check
filemd5=`md5sum $file | cut -d " " -f1`

# check the md5 and
# show an error when we check an empty file
if [ -z $filemd5 ]
    then
        echo "The file is empty - aborting"
        exit 1
    else
        # pass silent
        :
fi

# do we have allready an saved fingerprint of this file?
if [ -f $fingerprintfile ]
    then
        # yup - get the saved md5
        savedmd5=`cat $fingerprintfile`

        # check again if its empty
        if [ -z $savedmd5 ]
            then
                echo "The file is empty - aborting"
                exit 1
        fi

        #compare the saved md5 with the one we have now
        if [ "$savedmd5" = "$filemd5" ]
            then
                # pass silent
                :
            else
                echo "File has been changed"

                # this does an beep on your pc speaker (probably)
                # you get this character when you do:
                # CTRL+V CTRL+G
                # this is a bit creepy so you can use the 'beep' command
                # of your distro
                # or run some command you want to
                echo 
        fi

fi

# save the current md5
# sure you don't have to do this when the file hasn't changed
# but you know I'm lazy and it works...
echo $filemd5 > $fingerprintfile

2

Je suis venu à la recherche d'une doublure sur MacOS. Réglé sur ce qui suit. Compilé et ajouté cet outil à mon chemin. Cela a pris moins de 30 secondes.

$ git clone git@github.com:sschober/kqwait.git
$ cd kqwait
$ make
$ mv kqwait ~/bin
$ chmod +x ~/bin/kqwait

Ensuite, je suis allé dans le répertoire dans lequel je souhaitais faire la veille. Dans ce cas, je souhaitais regarder un fichier de démarque pour les changements, et si changé, éditez a make.

$ while true; do kqwait doc/my_file.md; make; done

C'est ça.


1
en tant que note, a bien fonctionné (si le contenu du fichier change), semble être uniquement OS X, et vous pouvez installer la vue brew install kqwaitet vous pouvez lui transmettre plusieurs fichiers commekqwait **/*
rogerdpack

0

Vous n'avez probablement pas besoin de comparer md5sum si vous disposez de l'utilitaire diff.

if ! diff "$file1" "$file2" >/dev/null 2>&1; then
  echo "$file1 and $file2 does not match" >&2
  ## INSERT-YOUR-COMMAND/SCRIPT-HERE
  ## e.g. cp "$file1" "$file2"
fi

le ! nie par exemple vrai si la déclaration est fausse

Attention, vous avez besoin du fichier d'origine pour comparer avec diff qui (imo) est identique à ce que fait le script md5sum ci-dessus.


Utilisez diff -q, si le diffsupporte.
muru

Ok essayons ça: echo foo> foo.txt; écho bar> bar.txt; diff foo.txt bar.txt -> Les fichiers foo et bar diffèrent ## (tellement pour être assez :))
Jetchisel

1
C'est plus silencieux que de préciser chaque différence. -qsignifie "signaler si seuls les fichiers diffèrent", et non en quoi ils diffèrent. Arrête donc de diff -qcomparer le moment où une différence est observée, ce qui peut être très utile en termes de performances. Voir la documentation GNU , par exemple. Si tout le point de votre réponse est efficace en n'utilisant pas md5sum, alors ne pas utiliser diff -qsi disponible est en train de vaincre ce point.
muru

Ok, -q "en termes de performances", c'est bien mais il imprime toujours quelque chose sur stdout / stderr si le fichier diffère les uns des autres. J'ai dit le! qui nie n'est-ce pas? ce que je recherche, c'est que l'état de sortie de diff n'est pas égal à 0 (voir la documentation GNU), puis prenez des mesures.
Jetchisel

Vous manquez le point. Je n'ai plus envie d'expliquer.
muru

0

Vous pouvez essayer l' entroutil de ligne de commande, par exemple

$ ls file1 | entr beep

entrdoit être installé ou du moins c'est le cas pour Ubuntu. Il devrait cependant être présent dans la plupart des référentiels distor.
rbaleksandar

0

si vous vérifiez les modifications dans un dépôt git, vous pouvez utiliser:

#!/usr/bin/env bash

diff="$(git diff | egrep some_file_name_or_file_path | cat)"

if [[ -n "$diff" ]] ; then
    echo "==== Found changes: ===="
    echo "diff: $diff"
    exit 1
else
    echo 'Code is not changed'
fi

0
Done in 2 steps Tested and worked fine in both scenarios

une. cp orginalfile fileneedto_be_changed'(Besoin de faire une seule fois)

orginalfile=====>which supposed to be changed

b.

differencecount=`awk 'NR==FNR{a[$0];next}!($0 in a){print $0}' orginalfile fileneedto_be_changed|wc -l`

if [ $differencecount -eq  0 ]
then
echo "NO changes in file"
else
echo "Noted there is changes in file"
fi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.