Terus memeriksa apakah file dimodifikasi bash


8

Saya memiliki file bernama file1 yang saya inginkan dalam sebuah skrip, setiap kali ada perubahan di dalamnya, lakukan sesuatu, bunyi bip sebenarnya. Bagaimana aku melakukan itu?

Jawaban:


14

Jika Anda telah inotify-toolsmenginstal (setidaknya itulah nama paket di Debian) ketika Anda dapat melakukan sesuatu seperti ini:

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

Ini menunggu peristiwa "modifikasi" terjadi pada file bernama "nama file". Ketika itu terjadi inotifywaitoutput perintah filename MODIFY(yang kita buang dengan mengirimkan output ke / dev / null) dan kemudian berakhir, yang menyebabkan tubuh loop dimasukkan.

Baca halaman manual inotifywaituntuk lebih banyak kemungkinan.


Poin baiknya, saya belum membaca halaman manual dengan baik :-)
wurtel

Anda tidak benar-benar membutuhkan while. Perhatikan juga bahwa apa yang oleh manusia dianggap sebagai "modifikasi" mungkin tidak selalu berfungsi: ini akan menangkap tambahan misalnya, tetapi tidak akan menangkap editor seperti vim(file yang ditonton diganti namanya atau ditukar dengan cadangan), atau perl -i(di tempat) sunting) yang menggantikan file dengan yang baru. Begitu salah satu dari itu terjadi, inotifywaittidak akan pernah kembali. Menonton inode dan menonton nama file bukan hal yang sama, jadi itu tergantung pada use case.
mr.spuratic

1
Anda dapat menambahkan acara lain untuk menunggu, misalnya move_selfakan menangkap nama. Lihat halaman manual untuk daftar lengkap acara.
Wurtel

2

Tanpa menunggu, Anda dapat menggunakan skrip kecil ini dan pekerjaan cron (setiap menit atau lebih):

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

Datang mencari one-liner di MacOS. Diselesaikan sebagai berikut. Kompilasi dan menambahkan alat ini ke jalur saya. Ini membutuhkan waktu kurang dari 30 detik.

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

Selanjutnya, saya pergi ke direktori di mana saya ingin menonton. Dalam hal ini, saya ingin menonton file penurunan harga untuk perubahan, dan jika ada perubahan, masalah a make.

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

Itu dia.


1
sebagai catatan, berfungsi dengan baik (jika konten file berubah), tampaknya hanya OS X, dan Anda dapat menginstal tampilan brew install kqwaitdan Anda dapat mengirimkan beberapa file ke dalamnya sepertikqwait **/*
rogerdpack

0

Anda mungkin tidak perlu membandingkan md5sum jika Anda memiliki utilitas diff yang tersedia.

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

itu! negates eg true jika pernyataan itu salah

Peringatan adalah Anda memerlukan file asli untuk membandingkan dengan diff yang (imo) sama dengan apa yang dilakukan skrip md5sum di atas.


Gunakan diff -q, jika diffmendukungnya.
muru

Ok mari kita coba itu: echo foo> foo.txt; echo bar> bar.txt; diff foo.txt bar.txt -> File foo and bar berbeda ## (sangat banyak karena cukup :))
Jetchisel

1
Itu lebih tenang daripada setiap perbedaan dijabarkan. -qberarti "laporkan jika hanya file berbeda", bukan perbedaannya. Jadi diff -qberhentilah membandingkan perbedaan saat dilihat, yang dapat menjadi kinerja yang sangat bijaksana. Lihat dokumentasi GNU , misalnya. Jika seluruh titik jawaban Anda menjadi efisien dengan tidak menggunakan md5sum, maka tidak menggunakan diff -qjika tersedia mengalahkan titik itu.
muru

Ok, -q "kinerja bijaksana" itu bagus tapi masih mencetak sesuatu ke stdout / stderr jika file berbeda satu sama lain. Saya menyatakan! yang meniadakan bukan? apa yang saya cari adalah status keluar dari diff bukan 0, (Lihat dokumentasi GNU) lalu ambil tindakan.
Jetchisel

Anda tidak mengerti intinya. Saya tidak punya keinginan lebih untuk menjelaskan.
muru

0

Anda dapat mencoba entralat baris perintah, mis

$ ls file1 | entr beep

entrperlu diinstal atau setidaknya itulah yang terjadi untuk Ubuntu. Itu harus hadir dalam repositori paling distor di luar sana.
rbaleksandar

0

jika Anda memeriksa perubahan dalam git repo, Anda dapat menggunakan:

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

Sebuah. cp orginalfile fileneedto_be_changed'(Hanya perlu melakukan satu kali)

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.