Узнайте, изменился ли файл - PullRequest
11 голосов
/ 26 февраля 2012

Я хочу выяснить, был ли файл изменен с момента последнего запуска моего сценария оболочки, возможно, путем создания логического значения или чего-то еще ... Возможно, можно было бы сохранить последний раз, когда сценарий запускался втекстовый файл, и когда скрипт запускается в следующий раз, он должен прочитать этот файл, а затем выяснить, какой файл был изменен, чтобы я мог проверить, изменился ли файл, используя что-то вроде:

for file in *
do
    #Somecode here
    if [ $filehaschanged != "0" ]; then
    echo "Foobar" > file.txt
    fi
    #Somecode here
done

Может быть, можно было бы сделать это с find ... любыми идеями?

Ответы [ 3 ]

19 голосов
/ 26 февраля 2012

Майкл, "изменено", вы спрашиваете, был ли файл затронут (т. Е. Datetamp новее), или вы спрашиваете, отличается ли содержимое?

Если первое, вы можете проверить это с помощью find или test. Например, в оболочке:

#!/bin/sh
touch file1
sleep 1
touch file2
if [ "file1" -nt "file2" ]; then
  echo "This will never be seen."
else
  echo "Sure enough, file1 is older."
fi

Если то, что вы ищете, это проверка содержимого, то ваша операционная система, вероятно, содержит что-то, что будет проверять хэш файла.

[ghoti@pc ~]$ date > testfile
[ghoti@pc ~]$ md5 testfile
MD5 (testfile) = 1b2faf8be02641f37e6d87b15444417d
[ghoti@pc ~]$ cksum testfile
3778116869 29 testfile
[ghoti@pc ~]$ sha1 testfile 
SHA1 (testfile) = 5f4076a3828bc23a050be4867549996180c2a09a
[ghoti@pc ~]$ sha256 testfile
SHA256 (testfile) = f083afc28880319bc31417c08344d6160356d0f449f572e78b343772dcaa72aa
[ghoti@pc ~]$ 

Я во FreeBSD. Если вы работаете в Linux, то, вероятно, вместо «md5» у вас есть «md5sum».

Чтобы поместить это в сценарий, вам нужно пройтись по списку файлов, сохранить их хеши, а затем иметь механизм для проверки текущих файлов по их сохраненным хешам. Сценарий достаточно прост:

[ghoti@pc ~]$ find /bin -type f -exec md5 {} \; > /tmp/md5list
[ghoti@pc ~]$ head -5 /tmp/md5list
MD5 (/bin/uuidgen) = 5aa7621056ee5e7f1fe26d8abb750e7a
MD5 (/bin/pax) = 7baf4514814f79c1ff6e5195daadc1fe
MD5 (/bin/cat) = f1401b32ed46802735769ec99963a322
MD5 (/bin/echo) = 5a06125f527c7896806fc3e1f6f9f334
MD5 (/bin/rcp) = 84d96f7e196c10692d5598a06968b0a5

Вы можете сохранить это (вместо / bin запустить его для всего важного, например, /) в предсказуемом месте, а затем написать быстрый скрипт для проверки файла по хешу:

#!/bin/sh

sumfile=/tmp/md5list

if [ -z "$1" -o ! -f "$1" ]; then
  echo "I need a file."
  exit 1
elif ! grep -q "($1)" $sumfile; then
  echo "ERROR: Unknown file: $1."
  exit 1
fi

newsum="`md5 $1`"

if grep -q "$newsum" $sumfile; then
  echo "$1 matches"
else
  echo "$1 IS MODIFIED"
fi

Этот вид сценария предназначен для таких инструментов, как tripwire .

1 голос
/ 26 февраля 2012

Вы можете touch всех файлов при запуске скрипта.Затем touch сам скрипт.
В следующий раз вы просто find любые файлы, которые новее, чем ваш скрипт.

0 голосов
/ 04 июня 2015
Решение

kev в Python, работает, если у вас есть права на прикосновение к сценарию:

#!/usr/bin/python 
import os
import sys

files= ('a.txt', 'b.txt')
me= sys.argv[0]
mytime= os.path.getmtime(me)
for f in files:
    ft= os.path.getmtime(f)
    if ft > mytime:
        print f, "changed"
os.utime(me, None)
...