Überprüfen Sie ständig, ob die Datei geändert wurde


8

Ich habe eine Datei namens file1, die ich in einem Skript haben möchte. Wenn sich etwas daran ändert, mache ich etwas, tatsächlich einen Piepton. Wie mache ich das?

Antworten:


14

Wenn Sie Folgendes inotify-toolsinstalliert haben (zumindest ist dies der Paketname auf Debian), können Sie Folgendes tun:

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

Dies wartet darauf, dass das Ereignis "Ändern" in der Datei mit dem Namen "Dateiname" auftritt. In diesem Fall wird der inotifywaitBefehl filename MODIFYausgegeben (den wir verwerfen, indem wir die Ausgabe an / dev / null senden) und dann beendet, wodurch der Hauptteil der Schleife eingegeben wird.

Lesen Sie die Manpage inotifywaitfür weitere Möglichkeiten.


Guter Punkt, ich hatte die Manpage nicht so gut gelesen :-)
wurtel

Sie brauchen nicht unbedingt while. Beachten Sie auch, dass das, was ein Mensch als "Ändern" ansieht, möglicherweise nicht immer funktioniert: Dies fängt beispielsweise einen Anhang ab, aber keinen Editor wie vim(die überwachte Datei wird umbenannt oder mit einem Backup ausgetauscht) oder perl -i(an Ort und Stelle) edit), die die Datei durch eine neue ersetzt. Sobald eines dieser Ereignisse eintritt, inotifywaitwird es nie mehr zurückkehren. Das Anschauen eines Inodes und eines Dateinamens ist nicht dasselbe, daher hängt es vom Anwendungsfall ab.
mr.spuratic

1
Sie können andere Ereignisse hinzufügen, auf die gewartet werden soll, z move_self. B. werden Umbenennungen abgefangen. Auf der Manpage finden Sie eine vollständige Liste der Ereignisse.
Wurtel

2

Ohne inotifywait können Sie dieses kleine Skript und einen Cron-Job verwenden (jede Minute oder so):

#!/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

Kam auf der Suche nach einem Einzeiler unter MacOS. Hat sich auf Folgendes geeinigt. Dieses Tool wurde kompiliert und meinem Pfad hinzugefügt . Dies dauerte weniger als 30 Sekunden.

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

Als nächstes ging ich zu dem Verzeichnis, in dem ich das Anschauen machen wollte. In diesem Fall wollte ich eine Markdown-Datei auf Änderungen überprüfen, und falls geändert, Ausgabe a make.

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

Das ist es.


1
Als Hinweis, hat gut funktioniert (wenn sich der Inhalt der Datei ändert), scheint nur OS X zu sein, und Sie können die Ansicht installieren brew install kqwaitund mehrere Dateien an sie übergeben, wiekqwait **/*
Rogerdpack

0

Sie müssen md5sum wahrscheinlich nicht vergleichen, wenn Sie das Dienstprogramm diff zur Verfügung haben.

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

das ! negiert zB true, wenn die Aussage falsch ist

Vorsichtsmaßnahme ist, dass Sie die Originaldatei benötigen, um sie mit diff zu vergleichen, was (imo) dasselbe ist wie das, was das md5sum-Skript oben tut.


Verwenden Sie diff -q, wenn es diffunterstützt.
Muru

Ok, lass es uns versuchen: echo foo> foo.txt; Echobar> bar.txt; diff foo.txt bar.txt -> Dateien foo und bar unterscheiden sich ## (so viel, um ganz zu sein :))
Jetchisel

Es ist leiser, als jeden Unterschied zu formulieren. -qbedeutet "melden, wenn sich nur Dateien unterscheiden", nicht wie sie sich unterscheiden. Hören Sie also diff -qauf, den Moment zu vergleichen, in dem ein Unterschied festgestellt wird, was in Bezug auf die Leistung sehr nützlich sein kann. Siehe zum Beispiel die GNU-Dokumentation . Wenn der ganze Punkt Ihrer Antwort effizient ist, indem Sie nicht verwenden md5sum, dann diff -qbesiegt das Nichtverwenden, falls verfügbar, diesen Punkt.
Muru

Ok, -q "leistungsmäßig" ist gut, aber es wird immer noch etwas nach stdout / stderr gedruckt, wenn sich die Datei voneinander unterscheidet. Ich sagte das! Welches Negat habe ich nicht? Was ich will, ist, dass der Exit-Status von diff nicht 0 ist (siehe GNU-Dokumentation) und dann Maßnahmen ergreift.
Jetchisel

Sie verpassen den Punkt. Ich habe keine weitere Lust zu erklären.
Muru

0

Sie können das entrBefehlszeilentool ausprobieren , z

$ ls file1 | entr beep

entrmuss installiert werden oder zumindest ist das bei Ubuntu der Fall. Es sollte jedoch in den meisten Distor-Repositories vorhanden sein.
Rbaleksandar

0

Wenn Sie Änderungen in einem Git-Repo überprüfen, können Sie Folgendes verwenden:

#!/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

ein. cp orginalfile fileneedto_be_changed'(Muss nur einmal machen)

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.