如果在上次执行后修改了Shell脚本来打印文件?

时间:2011-12-22 18:27:32

标签: bash shell

我需要编写一个Linux shell脚本,它可以扫描根目录并打印上次执行后修改过的文件。

例如,如果文件A昨天执行并且我今天修改它,则shell脚本必须打印文件A.但是,如果文件B昨天执行但我还没有修改它,则不应打印文件B.

3 个答案:

答案 0 :(得分:2)

您的主要问题是跟踪文件的执行时间。

麻烦的是,Linux没有单独跟踪文件执行的时间,而不是为了其他目的(例如备份或审查)读取文件,因此开始运行将非常棘手。

可以考虑各种各样的技巧,但这些技巧都不是特别琐碎或诱人的。一种选择可能是启用进程记帐。另一个可能是修改每个脚本以便在执行时进行记录。

“上次访问”时间(或atimest_atime,基于struct stat中包含该信息的字段的名称)对您没有帮助,因为,已经注意到,每当读取文件时它都会被修改。虽然肯定会访问已执行的文件,但可能有许多读取访问不执行该文件但会触发更新访问时间。

有了这些警告,可能是访问时间是您可以做的最好的,并且您的脚本需要查找访问时间等于修改时间的文件(这意味着文件已被修改,自修改以来未被访问 - 既不读也不打印也不执行。它不是完美的,但它可能是最好的近似值,缺少复杂的执行跟踪系统。

一旦你有一个机制来跟踪文件的执行时间,你就可以设计一个合适的方法来计算自上次执行以来哪些文件被修改过。

答案 1 :(得分:0)

在shell中执行此操作非常困难,因为很难在shell中以合理的格式获取atimemtime。考虑将例程移动到更全功能的语言,如Ruby或Perl:

ruby -e 'puts Dir["**/*"].select{ |file| File.mtime(file) > File.atime(file) }'

对当前目录及以下的所有文件使用**/*,对于以下当前目录中的所有Ruby脚本**/*.rb,对于root中的所有文件使用/* ...您将获得模式

请注意我在@JohanthanLeffer的评论中所写的内容:UNIX不区分读取文件和执行文件。因此,就此过程而言,使用cat ./script打印脚本与使用./script执行脚本具有相同的效果。除了制作自己的内核之外,没有办法区分我能想到的阅读和执行。

但是,在大多数情况下,您可能不会阅读可执行文件;如果您编辑它们,则会在打开后进行保存,因此mtime仍会胜过atime。唯一不好的情况是,如果您在编辑器中打开文件然后退出而不保存它(或只是使用less查看它,而不进行修改)。只要你避免这种情况,该方法就可以了。

另请注意,大多数编辑器实际上不会修改文件,而是创建新文件并从旧文件中复制内容,然后用新文件覆盖旧文件。这不会设置mtime,而是ctime。如果这是您的使用模式,请相应地修改脚本。

编辑:显然,stat可以帮助明智的表现形式。这是bash

#!/bin/sh                                                                   

for FILE in `find .`; do
  if [ `stat -f "%m -gt %a" $FILE` ]; then
    echo $FILE
  fi
done

"find ."(带反引号)替换为*仅用于当前目录,或/*替换为root。要使用ctime代替mtime,请使用%c代替%m

答案 2 :(得分:0)

Unix系统为任何文件存储3个时间值:

  1. 最后一次访问
  2. 最后修改
  3. 最后一次改变。
  4. 我不认为你可以在不使用某些人为手段的情况下获得上次执行时间,例如在可执行文件运行时创建日志或临时文件等。

    PS:请记住,并非Unix中的每个文件都是可执行文件,因此他们可能从未考虑过存储文件的last execution timestamp

    但是,如果您确实想获得这些时间值,请使用:

    stat -c "%X" file-name # to get last accessed time value as seconds since Epoch
    stat -c "%Y" file-name # to get last modified time value as seconds since Epoch
    stat -c "%Z" file-name # to get last change time value as seconds since Epoch