不断检查文件是否被修改bash


Answers:


14

如果已经inotify-tools安装(至少是Debian上的软件包名称),则可以执行以下操作:

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

这等待名为“文件名”的文件发生“修改”事件。发生这种情况时,inotifywait命令输出filename MODIFY(通过将输出发送到/ dev / null将其丢弃),然后终止,这将导致输入循环的主体。

阅读手册页以inotifywait获得更多可能性。


好点,我还没看完手册页:-)
Wurtel

您并非绝对需要while。另请注意,人们认为“修改”的内容可能并不总是有效:例如,它将捕获一个追加,但不会捕获诸如vim(观看的文件被重命名或与备份交换)之类的编辑器,也不会perl -i(就地)编辑),用新文件替换文件。一旦这两种情况发生,inotifywait就永远不会回来。看一个索引节点和看一个文件名不是完全一样的,所以这取决于用例。
spuratic先生2014年

1
您可以添加其他事件以等待,例如move_self将捕获重命名。有关事件的完整列表,请参见手册页。
wurtel

2

如果没有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

在MacOS上寻找单线。解决以下。编译并将此工具添加到我的路径中。此过程不到30秒。

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

接下来,我转到了要观看的目录。在这种情况下,我希望查看markdown文件中的更改,如果更改,请发出make

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

而已。


1
值得注意的是,它运作良好(如果文件内容更改),似乎仅适用于OS X,并且您可以安装view brew install kqwait并可以将多个文件传递给它kqwait **/*
-rogerdpack

0

如果您具有diff实用程序,则可能不需要比较md5sum。

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脚本所做的相同。


diff -q如果diff支持,请使用。
muru

好的,让我们尝试一下:echo foo> foo.txt; 回声栏> bar.txt; diff foo.txt bar.txt->文件foo和bar不同##(
实在

1
比说明所有差异要安静。-q表示“如果只有文件不同则报告”,而不是不同之处。因此,diff -q停止比较发现差异的那一刻,这可能是非常有用的性能明智的选择。例如,请参阅GNU文档。如果您的答案的全部要点是通过不使用来提高效率md5sum,那么不使用(diff -q如果可用)将使该点无效。
muru

好的,-q“性能明智”是好的,但是如果文件彼此不同,它仍然会向stdout / stderr打印一些内容。我说了!我不是哪个否定主义者?我需要的是diff的退出状态不为0(请参阅GNU文档),然后采取措施。
Jetchisel

您错过了重点。我不想再解释了。
muru

0

您可以尝试使用entr命令行工具,例如

$ ls file1 | entr beep

entr需要安装,或者至少对于Ubuntu就是这样。但是,它应该存在于大多数Distor存储库中。
rbaleksandar

0

如果要检查git repo中的更改,则可以使用:

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

一个。cp orginalfile fileneedto_be_changed'(只需要做一次)

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.