Bash 如果上次执行后修改,是否使用Shell脚本打印文件?

Bash 如果上次执行后修改,是否使用Shell脚本打印文件?,bash,shell,Bash,Shell,我需要编写一个Linux shell脚本,它可以扫描根目录并打印上次执行后修改的文件 例如,如果文件A昨天执行,而我今天修改了它,则shell脚本必须打印文件A。但是,如果文件B昨天执行,而我尚未修改它,则不应打印文件B。您的主要问题是跟踪文件执行的时间 问题是,Linux没有单独跟踪文件的执行时间,而不是出于备份或审阅等其他目的读取文件的时间,因此要开始操作将非常困难 有各种各样的技巧可以考虑,但没有一个是特别琐碎或吸引人的。一个选项可能是启用流程记帐。另一种可能是修改每个脚本,以便在执行时进

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


例如,如果文件A昨天执行,而我今天修改了它,则shell脚本必须打印文件A。但是,如果文件B昨天执行,而我尚未修改它,则不应打印文件B。

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

问题是,Linux没有单独跟踪文件的执行时间,而不是出于备份或审阅等其他目的读取文件的时间,因此要开始操作将非常困难

有各种各样的技巧可以考虑,但没有一个是特别琐碎或吸引人的。一个选项可能是启用流程记帐。另一种可能是修改每个脚本,以便在执行时进行记录

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

有了这些注意事项,访问时间可能是您所能做的最好的了,您的脚本需要查找访问时间等于修改时间的文件,这意味着该文件已被修改,并且自修改后未被访问-既不读取,也不打印,也不执行。它还不够完美,但它可能是可用的最佳近似值,缺少复杂的执行跟踪系统


一旦有了跟踪文件执行时间的机制,就可以设计出一种适当的方法来确定自上次执行以来修改了哪些文件。

在shell中很难做到这一点,因为很难在shell中以合理的格式获取atime或mtime。考虑将例程移动到一个更全面的语言,如Ruby或Perl:

ruby -e 'puts Dir["**/*"].select{ |file| File.mtime(file) > File.atime(file) }'
对当前目录及以下目录中的所有文件使用***/*,对以下目录中当前目录中的所有Ruby脚本使用***/.rb,/*对根目录中的所有文件。。。你明白了

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

然而,在大多数情况下,您可能不会读取可执行文件;如果你编辑它们,打开后会保存,所以mtime仍然会超过atime。唯一糟糕的情况是,如果您在编辑器中打开一个文件,然后退出而不保存它,或者只查看它而不进行修改。只要您避免这种情况,该方法就会起作用

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

编辑:显然,stat可以帮助进行合理的表示。这是在bash中:


替换查找。使用带*的反勾号表示当前目录,或使用/*表示根目录。要使用ctime而不是mtime,请使用%c而不是%m。

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

最后访问 最后修改 最后的零钱。 我认为,如果不使用一些人工方法,比如在可执行文件运行时创建日志或临时文件等,就无法获得最后一次执行时间

PS:请记住,并不是Unix中的每个文件都是可执行文件,所以这可能是他们从未想过存储文件最后一次执行时间戳的原因

但是,如果确实要获取这些时间值,请使用:

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
在atime中确实如此,但并不完美——读取文件也会设置atime,就像执行它一样。
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