【问题标题】:Bash script — determine if file modified?Bash 脚本——判断文件是否被修改?
【发布时间】:2011-01-14 21:26:41
【问题描述】:

我有一个每 5 秒重复复制文件的 Bash 脚本。但这有点矫枉过正,因为通常没有变化。

我知道 Linux 命令 watch,但由于此脚本将用于 OS X 计算机(没有 watch,而且我不想让每个人都安装 macports)我需要能够使用直接 Bash 代码检查文件是否被修改。

我应该检查文件修改时间吗?我该怎么做?

编辑:如果检测到更改,我希望扩展我的脚本来做的不仅仅是复制文件。那么有没有一种纯粹的方式来做到这一点?

【问题讨论】:

  • 也许您可以改用rsync?它可以将时间戳和大小与目标文件的时间戳和大小进行比较,如果它们相同,则避免复制。 (不过,如果您要复制到远程机器,仍然会有连接开销。)

标签: macos bash


【解决方案1】:

如果您有大量文件,我倾向于同意rsync 的答案 进行管理,但您可以使用 -u (--update) 标志来 cp 复制 仅当源比目标更新时文件才被覆盖。

cp -u

编辑

由于您已更新问题以表明您愿意参加 一些额外的操作,你会想要使用-nt检查 在[ (test) 内置命令中:

#!/bin/bash

if [ $1 -nt $2 ]; then
  echo "File 1 is newer than file 2"
else
  echo "File 1 is older than file 2"
fi

来自手册页:

file1 -nt file2
         True if file1 is newer (according  to  modification  date)  than
         file2, or if file1 exists and file2 does not.

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    OS X 有stat 命令。像这样的东西应该给你一个文件的修改时间:

    stat -f '%m' filename
    

    GNU 等价物是:

    stat --printf '%Y\n' filename
    

    【讨论】:

      【解决方案3】:

      您可能会发现通过比较文件大小(如果大小不同,则内容不同)和内容的哈希来检测文件内容的变化更可靠。您为此目的使用哪种哈希可能并不重要:SHA1 甚至 MD5 可能就足够了,您可能会发现 cksum 命令就足够了。

      文件修改时间可以在不改变内容的情况下改变(想想touch file);文件修改时间即使内容改变也不能改变(这样做比较困难,但您可以在编辑文件后使用touch -r ref-file file设置file的修改时间以匹配ref-file)。

      【讨论】:

      • 为什么使用哈希而不是逐位比较?逐位比较不是比遍历整个文件并形成它的哈希更快吗?
      • @Pacerier:如果文件不同,那么逐字节比较可能会更快,除非最后一个字节是唯一不同的。如果文件相同,则只能通过比较所有字节来显示。哈希的优点是可以存储哈希的旧值(相对较小),并将其与从当前文件重新生成的哈希的新值进行比较。如果有差异,则文件已更改。进行逐字节比较需要存在旧文件。
      【解决方案4】:

      没有。您应该使用rsync 或其前端之一来复制文件,因为它会检测文件是否不同并且仅在不同时复制它们。

      【讨论】:

      • rsync 是一个有用的建议(尽管您可以在我的编辑中看到,这不是我所需要的)。但我觉得你的语气有点反感。
      • @Alan H.:也许我遗漏了一些东西,但我一点也不觉得语气令人反感。事实上,我对你的反应感到惊讶。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      相关资源
      最近更新 更多