我正在尝试做我认为在Linux下很简单的事情。我有一个运行各种测试程序的bash脚本,我想确定当前目录中的哪些文件是由测试程序创建的。所以我正在做这样的事情:
touch timestamp-file run the test find -newer timestamp-file -type f > list-of-files rm -f timestamp-file
结果发现-newer的粒度很差,所以通常会发生的情况是测试程序生成的某些文件显示为OLDER而不是timestamp文件。所以我试过这个:
ls -tr1 | sed '1,/timestamp-file/d'
生成相同的列表。这个通常有效,但并非总是如此。我仍然认为测试生成的文件显示为比timestamp文件旧的情况。
谢谢!
P.S。我可以通过获取目录的两个快照来实现另一种方式,一个在测试程序运行之前,一个之后,然后比较它们。第二个列表中不在第一个文件中的任何文件必须由测试程序创建(我不关心后台作业或写入目录的其他用户)。但是这个方法不是我想要的,因为如果在运行测试之前没有删除输出文件(它们应该是,但在某些情况下它们可能不是),这个方法会说它不是由测试程序,因为它在测试程序运行之前就在dir中。
答案 0 :(得分:3)
您实际上可以使用touch强制将目录中所有当前文件的时间戳强制推迟到过去,例如:
touch -t 200801010000.00 *
如果您在运行测试之前执行此操作,“find -newer
”获取它的时间应该有足够的差异。如果粒度为两分钟,则可以将所有当前文件设置为10分钟前,将时间戳文件设置为5分钟前,然后运行测试。
所以你的脚本变成了:
touch -t (current time - 10 minutes) *
touch -t (current time - 5 minutes) timestamp-file
run the test
find -newer timestamp-file -type f > list-of-files
rm -f timestamp-file
假设你有一个不错的Perl安装,你可以使用正确的“date -t
”格式在5分钟前(或使用-600 10分钟)执行以下操作:
use Date::Manip;
print UnixDate(DateCalc(ParseDateString("now"),"-300"),"%Y%m%d%H%M.%S") . "\n";
如果出于某种原因,您不允许更改时间戳,请使用:
sleep 300
touch timestamp-file
sleep 300
run the test
find -newer timestamp-file -type f > list-of-files
rm -f timestamp-file
具有相同的效果,但是给你十分钟的时间去喝咖啡(或者如果你不是咖啡饮用者,你会选择你的毒药)。
答案 1 :(得分:2)
如果您考虑如何实施find(1)
,那么很明显为什么这有时可能无法按预期发挥作用。这是一个提示:
$ touch timestamp ; touch newer ; find . -newer timestamp
$ rm timestamp newer
$ touch timestamp ; sleep 1 ; touch newer ; find . -newer timestamp
.
./newer
$
find(1)
使用系统调用stat(2)
获取文件mtime / ctime / atime值。以下是来自struct stat
(Linux)<sys/stat.h>
的元素:
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
在Linux上(通常是unices)time_t
是一个表示“从1970年开始的秒数”的整数。因此,-newer
可以理解的最细微的粒度只是一秒钟。
答案 2 :(得分:1)
在运行之前获取所有文件的文件名,但包括它们的时间戳:
find -printf '%p %T@\n' | sort > file1
如果您还没有找到该选项,您也可以使用该职位的统计数据:
find -print0 | xargs -0 stat -c "%n %Y" | sort > file1
跑到file2
之后。然后使用
comm -1 -3 file1 file2
它会显示file2
唯一的行,如果我没记错的话,必须是新文件。如果它们之前存在,它们的修改时间将会发生变化,这由%T@
事物处理(打印出自1970年以来的秒数):
[js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file1 [js@HOST2 cpp]$ echo foo>bar [js@HOST2 cpp]$ echo foo>baz [js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file2 [js@HOST2 cpp]$ comm -1 -3 file1 file2 . 1230947309.0000000000 ./bar 1230947308.0000000000 ./baz 1230947309.0000000000 ./file2 1230947315.0000000000 [js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file1 [js@HOST2 cpp]$ echo lol>bar [js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file2 [js@HOST2 cpp]$ comm -1 -3 file1 file2 ./bar 1230947359.0000000000 ./file2 1230947362.0000000000 [js@HOST2 cpp]$`
答案 3 :(得分:0)
为什么不创建一个运行测试的临时目录?在目录上使用基于时间戳的名称来帮助跟踪发生的结果,并在完成后简单地删除整个目录。