Постійно перевіряйте, чи файл змінено bash

У мене є файл з назвою file1, який я хочу в сценарії, коли змінюється, щось робити, звуковий сигнал. Як це зробити?

7

5 Відповіді

Якщо ви встановили inotify-tools (принаймні, це назва пакета на Debian), коли ви можете зробити щось подібне:

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

Це очікує, що подія "modify" відбудеться з файлом з ім'ям "filename". Коли це відбудеться, команда inotifywait виводить ім'я файлу MODIFY (яку ми відкидаємо, надіславши вихід до/dev/null), а потім завершується, що призводить до того, що тіло циклу буде введено.

Прочитайте сторінку inotifywait для отримання додаткових можливостей.

12
додано
Вам не обов'язково потрібно while . Також зверніть увагу, що те, що людина розглядає як "модифікувати", може не завжди спрацювати: це призведе до прикладу, наприклад, до додавання, але він не зможе схопити редактор, наприклад, vim (файл, який переглядається, перейменований або замінений на резервної копії), а також perl -i (редагування на місці), яка замінює файл новим. Коли це станеться, inotifywait ніколи не повернеться. Переглядаючи inode та переглядаючи ім'я файлу, це не зовсім однаково, тому це залежить від випадку використання.
додано Автор Brad, джерело
Хороший пункт, я не читав manpage, що добре :-)
додано Автор Tom Carpenter, джерело
Можна додати інші події для очікування, наприклад, move_self захопить перейменування. Див. Сторінку для повного списку подій.
додано Автор Tom Carpenter, джерело

Приїхав шукати один лайнер на MacOS. Розрахувалися на наступне. Скомпілював і додав цей інструмент до мого шляху. Це зайняло менше 30 секунд.

$ git clone [email protected]:sschober/kqwait.git
$ cd kqwait
$ make
$ mv kqwait ~/bin
$ chmod +x ~/bin/kqwait

Далі я перейшов до каталогу, в якому я хотів зробити перегляд. У цьому випадку я хотів би переглядати файл відмітки для внесення змін, а якщо змінити - видати make .

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

Це воно.

3
додано
як примітка, добре працювала (якщо зміна вмісту файлу), здається, лише OS X, і ви можете встановити вигляд brew install kqwait , і ви можете передати до нього декілька файлів, як kqwait **/*
додано Автор globus25, джерело

Без inotifywait можна використовувати цей маленький скрипт і завдання cron (кожну хвилину або близько того):

#!/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
додано

Можна спробувати entr інструмент командного рядка, наприклад,

$ ls file1 | entr beep
0
додано
entr потрібно встановити або, принаймні, це так для Ubuntu. Вона повинна бути присутнім у більшості сховищ дистрибутивів.
додано Автор rbaleksandar, джерело

Можливо, вам не потрібно порівнювати md5sum, якщо у вас є утиліта 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

! заперечує, наприклад, true, якщо твердження помилкове

Будьте впевнені, що вам потрібен оригінальний файл для порівняння з diff, який (imo) такий же, як і сценарій md5sum.

0
додано
Використовуйте diff -q , якщо його підтримує diff .
додано Автор muru, джерело
Це тихіше, ніж будь-яка різниця. -q означає "повідомити, якщо відрізняються лише файли", а не те, як вони відрізняються. Отже, diff -q припиняє порівняти момент, коли видно різницю, що може бути дуже корисним. Див., Наприклад, документацію GNU . Якщо вся справа у вашій відповіді є ефективною, не використовуючи md5sum , то, не використовуючи diff -q , якщо вона доступна, вона перемагає цю точку.
додано Автор muru, джерело
Ви не знаєте про це. У мене немає іншого бажання пояснювати.
додано Автор muru, джерело
Добре, спробуємо це: echo foo> foo.txt; echo bar> bar.txt; diff foo.txt bar.txt -> Файли foo і bar відрізняються ## (стільки за те, що ви цілком :))
додано Автор user99037, джерело
Добре, -q "performance wise" це добре, але все одно друкує щось у stdout/stderr, якщо файл відрізняється один від одного. Я заявив! які нівелювали не я? те, що я після цього, це статус виходу diff, який не дорівнює 0, (див. документацію GNU), а потім виконайте дії.
додано Автор user99037, джерело