我运行一个 SSH 服务器(普通sshd
),它通过 SFTP 从不同时区/DST 的多个用户接收文件。然后,一组工作作业会轮询并进一步处理这些文件。
为了防止文件未被处理(错误或缓慢的工作进程等),我决定实施一个简单的检查,检查所有 SFTP 映射的目录并报告所有文件比 X 年长。
问题是服务器上 SFTP 接收的文件明显具有以下特征用户时间戳中的本地时区/DST对于mtime
和 - 令我惊讶的是 - 甚至ctime
。这会导致检查无法检测到以正时区偏移到达的文件,并立即报告以负时区偏移到达的文件。
我似乎无法找到一种方法来将接收到的文件的时间戳规范化为服务器的本地时区或 UTC。
答案1
您可以将 sftp 服务器配置为拒绝更改文件时间戳的请求。查找/etc/ssh/sshd_config
当前配置行,在我的例子中是
Subsystem sftp /usr/libexec/openssh/sftp-server
运行服务器并-Q
选择列出可以发出的请求:
/usr/libexec/openssh/sftp-server -Q requests
就我而言,这包括setstat
并且fsetstat
可能与时代的变化相对应。使用黑名单选项-P
拒绝sshd_config
文件中的这些请求:
Subsystem sftp /usr/libexec/openssh/sftp-server -P setstat,fsetstat
通过使用 SIGHUP 信号终止配置来通知sshd
重新读取配置。
当我然后sftp
尝试放将文件发送到服务器,并带有-p
保留时间的选项,该文件已被复制,但其上次修改时间仍为“现在”。客户看到了一条警告,您必须向您的用户介绍以下内容:
sftp> put -p localfile remotefile
Uploading localfile to remotefile
Couldn't fsetstat: Permission denied
答案2
我看到的解决这个问题的一个办法是,你touch
一收到文件就立即归档。这将修改这些文件的访问和修改时间戳。
来源:触摸手册
答案3
如果您没有大量文件,则可以用于inotifywait
监视新文件到达并修复其时间戳。 (默认限制是 8192 个文件和目录。您可以增加此限制,但增加太多可能不是一个好主意,因为它的成本很高)。例如,要查找写入后关闭的文件,或者递归地查找目录下权限或时间属性的更改/dir
:
inotifywait -m -r -e close_write -e attrib /dir
它连续运行并会输出类似
/dir/subdir ATTRIB filea
/dir/subdir CLOSE_WRITE,CLOSE filea
对于文件的更改/dir/subdir/filea
。您可以编写一个 shell 脚本来重建文件名$f
(注意带空格的名称),然后使用stat -c %Z $f
获取其当前修改时间,并将其与date +%s
.如果绝对差异超过几秒,您可以使用touch
更改文件时间(这将生成一个新事件,因此需要忽略时间上的微小差异)。