ファイルが変更されているかどうかを常に確認するbash


8

スクリプトに追加したいfile1というファイルがあります。ファイルに変更があるたびに、何かを実行します。実際にはビープ音が鳴ります。それ、どうやったら出来るの?

回答:


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。これは、例えばAPPENDをキャッチしますが、それはのようなエディタをキャッチしません。また、人間が考えるもの「変更」ではない、常に仕事がかもしれないことに注意してくださいvim(ファイル名前を変更したり、バックアップと交換されて見て)、またperl -i(インプレースedit)ファイルを新しいファイルに置き換えます。これらのいずれかが発生すると、inotifywait二度と戻りません。iノードの監視とファイル名の監視はまったく同じではないため、ユースケースによって異なります。
mr.spuratic 2014年

1
他のイベントを追加して待機することができmove_selfます。たとえば、名前の変更をキャッチします。イベントの完全なリストについては、マンページを参照してください。
ヴルテル2014年

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

次に、見たいと思ったディレクトリに行きました。この場合、私はマークダウンファイルの変更を監視し、変更された場合はを発行したいと考えていましたmake

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

それでおしまい。


1
メモとして、うまく機能しました(ファイルの内容が変更された場合)、OS Xのみのように見え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

!ステートメントが偽の場合、例えば真を否定します

警告は、上記のmd5sumスクリプトが行っていることと同じ(imo)diffと比較するために元のファイルが必要なことです。


サポートしているdiff -q場合diffは、を使用します。
muru

それでは試してみましょう:echo foo> foo.txt; エコーバー> bar.txt; diff foo.txt bar.txt->ファイルfooとbarは##が異なります(かなりのことですが:))
Jetchisel

1
すべての違いを説明するよりも静かです。-q「ファイルのみが異なる場合にレポートする」ことを意味し、それらがどのように異なるかではありません。したがってdiff -q、違いが見られた瞬間に比較を停止します。これは、賢明なパフォーマンスにとって非常に役立ちます。たとえば、GNUドキュメントを参照してください。あなたの答えの全体のポイントがを使用しないことで効率的である場合、もし可能であれば使用しmd5sumないことdiff -qはそのポイントを打ち負かします。
muru

OK、-q "パフォーマンス的に賢い"ですが、ファイルが異なる場合でも、標準出力/標準エラー出力に出力されます。私は述べました!私は否定していませんか?私の後には、diffの終了ステータスが0でない(GNUのドキュメントを参照)後、アクションを実行します。
Jetchisel 2015年

あなたは要点を逃しています。これ以上説明したくありません。
muru

0

entrコマンドラインツールを試すことができます。

$ ls file1 | entr beep

entrインストールする必要があります。少なくともUbuntuの場合はそうです。ただし、ほとんどのディストーションリポジトリに存在するはずです。
rbaleksandar

0

gitリポジトリの変更を確認する場合は、次のコマンドを使用できます。

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

a。cp orginalfile fileneedto_be_changed'(1回だけ実行する必要があります)

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.