Find out if file has changed

前端 未结 3 1682
耶瑟儿~
耶瑟儿~ 2021-02-05 18:14

I want to find out if a file has been modified since the last time my shell script was started, maybe by creating a boolean or something... Maybe it would be possible to save th

相关标签:
3条回答
  • 2021-02-05 18:57

    kev's solution in Python, works if you have permissions to touch the script:

    #!/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)
    
    0 讨论(0)
  • 2021-02-05 19:04

    Michael, by "changed", are you asking if the file has been touched (i.e. datestamp is newer), or are you asking if the content is different?

    If the former, you can test this with find or test. For example, in shell:

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

    If what you're looking for is a test of the contents, then your operating system probably includes something that will test the hash of a file.

    [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 ~]$ 
    

    I'm in FreeBSD. If you're in Linux, then you probably have "md5sum" instead of "md5".

    To put this into a script, you'd need to walk through your list of files, store their hashes, then have a mechanism to test current files against their stored hashes. This is easy enough to script:

    [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
    

    You can store this (instead of /bin run it against whatever's important, perhaps /) in a predictable location, then write a quick script to check a file against the hash:

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

    This kind of script is what tools like tripwire provide.

    0 讨论(0)
  • 2021-02-05 19:17

    You can touch all files when you run your script. Then touch the script itself.
    Next time, you just find any files which is newer than your script.

    0 讨论(0)
提交回复
热议问题