【问题标题】:Find out if file has changed查看文件是否已更改
【发布时间】:2012-03-16 06:07:23
【问题描述】:

我想知道自上次启动我的 shell 脚本以来文件是否被修改过,可能是通过创建一个布尔值或其他什么... 也许可以将上次运行脚本的时间保存在文本文件中,并且下次启动脚本时它应该读取此文件,然后它应该找出已更改的文件,以便我可以检查是否文件已使用以下内容更改:

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

也许用find...有什么想法可以做到这一点?

【问题讨论】:

标签: shell unix find boolean


【解决方案1】:

Michael,通过“更改”,您是在询问文件是否已被触摸(即日期戳较新),还是您在询问内容是否不同?

如果是前者,您可以使用findtest 进行测试。例如在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

如果您要查找的内容是对内容的测试,那么您的操作系统可能包含将测试文件哈希的内容。

[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,那么您可能使用的是“md5sum”而不是“md5”。

要将其放入脚本中,您需要遍历文件列表,存储它们的哈希值,然后有一种机制来根据存储的哈希值测试当前文件。这很容易编写脚本:

[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之类的工具提供的。

【讨论】:

    【解决方案2】:

    您可以在运行脚本时touch所有文件。然后touch脚本本身。
    下次,您只需find 任何比您的脚本更新的文件。

    【讨论】:

    • 好主意 touch myscript.sh | touch * | find ???
    • 是的,这是一个聪明的想法,除了在具有合理安全设置的较大系统中,运行脚本的用户可能不应该有权修改脚本或其时间戳。为了更便携/更安全,我建议触摸 /tmp 或 /var/tmp 中的一个文件,作为时间比较。
    • @MichealPerr 只需将 touch 命令放在脚本末尾
    • 在脚本中,$0 是脚本的名称。因此,如果您想使用这种方法,只需在脚本末尾添加 touch "$0" 即可。 (引号是为了防止您决定将空格等有趣的字符放入脚本的文件名中。在 shell 脚本中将变量括在引号中总是一个好主意。)
    【解决方案3】:

    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)
    

    【讨论】:

      猜你喜欢
      • 2010-12-18
      • 2018-09-13
      • 2010-09-08
      • 2012-05-05
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      相关资源
      最近更新 更多