9

我正在尝试使用 ruby​​ 脚本为 Mac OS 上的文件设置文件系统创建时间。

在 Mac OS X 上,'ctime' 代表最后一次 inode 修改时间,而不是文件创建时间,因此使用 ruby​​ 的 File.utime() 设置 ctime 无济于事。

使用此提示 [ http://inessential.com/2008/12/18/file_creation_date_in_ruby_on_macs ] 我可以检索文件的创建时间:

Time.parse(`mdls -name kMDItemContentCreationDate -raw "#{filename}"`)

...但是关于如何使用 ruby​​ 设置它的任何想法?

- 更新 -

好的,我想我实际上可以用 ruby​​ 做到这一点File.utime

即使 Mac OS 在技术上不使用 ctime 来跟踪文件创建时间,但当您使用utime更新ctime(以及必须同时设置的mtimekMDItemContentCreationDate )时,文件系统似乎也神奇地按照.

因此,要将文件名设置为 2010 年 10 月 1 日的 ctime 和 2010 年 10 月 2 日的 mtime:

File.utime(Time.strptime('011010', '%d%m%y'), Time.strptime('021010', '%d%m%y'), filename)
4

4 回答 4

15

There is a Ruby solution with the method utime. But you will have to set modification time (mtime) and access time (atime) at once. If you want to keep access time you could use:

File.utime(File.atime(path), modification_time, path)

See Ruby core documentation as well.

于 2012-08-28T07:03:25.607 回答
3

所以你肯定有一个纯 Ruby 解决方案可以工作,但是因为这是 OS X,你反对exec()还是system()仅仅使用touch? 在你的情况下,我几乎更喜欢:

system "touch -t YYYYMMDDhhmm /what/ever"

如果没有其他原因,只是为了清楚。

于 2011-12-24T19:54:03.650 回答
2

This works for me to update creation time on OS X 10.11.1:

system "SetFile -d '#{time.strftime "%m/%d/%Y %H:%M:%S"}' #{file}"

No claims of portability - SetFile is an OS X command (and the man page says it's deprecated with XCode 6, so may not work for very long) - couldn't find another way to do it though, Time.utime didn't update creation time, but only modified and accessed time.

See: https://apple.stackexchange.com/q/99536/65787

于 2016-02-08T18:38:22.307 回答
0

Ruby uses the utimes system call to change the file-times.

Reading the man-page for utimes explains what happens:

int utimes(const char *path, const struct timeval *times); .. If times is non-NULL, it is assumed to point to an array of two timeval structures. The access time is set to the value of the first element, and the modification time is set to the value of the second element. For file systems that support file birth (creation) times (such as UFS2), the birth time will be set to the value of the second element if the second element is older than the currently set birth time. To set both a birth time and a modification time, two calls are required; the first to set the birth time and the second to set the (presumably newer) modification time. ...

So ctime only get updated backwards in time.

于 2017-10-02T10:11:28.097 回答