【问题标题】:Last change time of a directory based on contained file contents?基于包含的文件内容的目录的最后更改时间?
【发布时间】:2012-04-07 14:07:08
【问题描述】:

是否可以在考虑更改文件内容的情况下计算目录的最后修改时间?

我们正在尝试查看一系列上传目录以确定用户 FTP 会话何时完成。

用户正在将一组文件上传到特定目录,我们想检测该目录中的最后一个文件在 N 分钟内没有更改的时间。 (我们使用它作为“FTP 会话完成”的代理。)

我们从这个开始查找空闲时间超过 5 分钟但不到 10 分钟的目录:

find . -mmin +5 -mmin -10 -type d -ls

此处使用的目录时间戳基于最近的文件添加到目录的时间。

我已阅读Directory last modified date,很明显,读取目录的 mtime 或 mmin 将不起作用,因为当目录中的文件更新其内容时它不会改变。因此,上述方法不起作用,因为如果最后一个文件是一个可能需要超过 10 分钟才能上传的大文件,那么在触发此操作时该目录将不会真正处于空闲状态(即所有文件都未更改)。

是否有基于 shell 的替代方案(最好是 find 命令的配置),它使用内部最后更改文件的 mtime 作为时间戳,但仍然在目录级别操作(即我们不想根据单个目录中的所有文件获得多次点击)?

【问题讨论】:

  • 考虑另一种解决方案,因为我认为您不会找到您正在寻找的选项(也许您可以编写代码)。如果您从商业来源获取文件作为合同的一部分,要求他们发送一个特殊的“标志”文件作为最后一个文件并不是不合理的。然后你可以循环,寻找标志文件,当它到达时,你可以开始你的处理(这应该包括一个验证步骤,以确保你在那里的所有文件,它们与昨天不同,不为空(除非可以),标志文件可以是大小的文件列表
  • 不幸的是,这些往往来自非常非技术的用户,他们只是将文件放入客户端 UI。我们正在寻求分发一个自定义客户端,该客户端将允许在幕后使用此标志方法,但我们仍然希望在自定义客户端部署不起作用的情况下作为备用方案

标签: shell directory find monitoring filesystemwatcher


【解决方案1】:

我同意@shellter 的评论,即标志文件是最好的方法。这取决于您的用户是否同意上传该文件。

在当前目录下查找最新的文件

find . -type f -printf "%T@ %p\n" | sort -nr | head -1

输出是2个字段:

  1. 自纪元以来的时间(以秒为单位,以微秒为单位)
  2. 文件的相对路径

【讨论】:

  • 谢谢格伦;这就是我一直在寻找的,至少是为了获得一个临时解决方案来工作
【解决方案2】:

我也在围栏的“替代解决方案”方面。

如果您有权访问 FTP 服务器的日志,我建议您跟踪该日志以观察是否成功上传。与您的问题中描述的轮询方法相比,这种事件触发方法将更快、更可靠且负载更少。

您处理此问题的方式当然取决于您的 FTP 服务器。我有一个正在运行的vsftpd,它的日志包括这样的行:

Fri Mar 23 07:36:02 2012 [pid 94378] [joe] OK LOGIN: Client "10.8.7.16"
Fri Mar 23 07:36:12 2012 [pid 94380] [joe] OK UPLOAD: Client "10.8.7.16", "/path/to/file.zip", 8395136 bytes, 845.75Kbyte/sec
Fri Mar 23 07:36:12 2012 [pid 94380] [joe] OK CHMOD: Client "10.8.7.16", "/path/to/file.zip 644"

UPLOAD 行仅在 vsftpd 成功保存文件后添加。你可以像这样在 shell 脚本中解析它:

#!/bin/sh

tail -F /var/log/vsftpd.log | while read line; do
  if echo "$line" | grep -q 'OK UPLOAD:'; then
    filename=$(echo "$line" | cut -d, -f2)
    if [ -s "$filename" ]; then
      # do something with $filename
    fi
  fi
done

这不是最漂亮的 shell 脚本,老实说,如果我自己使用它,我可能会写得有点不同,但这很好地说明了这个想法。

【讨论】:

  • 在 while 循环的底部有一个 sleep 60 或 300 或 600,对吗? ;-) 不错的替代品!
  • 谢谢。实际上,您不希望在 while 循环的底部出现“睡眠”,除非您有理由在处理下一个上传的文件之前延迟。由于您使用的是tail -F,因此日志输出只会为新的日志条目触发循环。一旦# do something 代码被执行,这个脚本就会等待新的日志数据通过。轮询解决方案需要延迟,但这是 event driven 而不是轮询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多