Reputation: 1229
I'm trying to set the filesystem creation time for a file on Mac OS using a ruby script.
On Mac OS X the 'ctime' represents the last time of inode modification rather than the file creation time, thus using ruby's File.utime() to set ctime will not help.
Using this hint [ http://inessential.com/2008/12/18/file_creation_date_in_ruby_on_macs ] I can retrieve a file's creation time:
Time.parse(`mdls -name kMDItemContentCreationDate -raw "#{filename}"`)
...but any idea on how to set it using ruby?
-- UPDATE --
Okay, I think I can actually do this with File.utime
in ruby.
Even though the ctime is technically not used by Mac OS to track file creation time, when you use utime
to update the ctime (along with the mtime, which must be simultaneously set) the filesystem appears to magically also update the creation time as per kMDItemContentCreationDate
.
So to set filename to a ctime of 1st Oct 2010 and a mtime of 2nd Oct 2010:
File.utime(Time.strptime('011010', '%d%m%y'), Time.strptime('021010', '%d%m%y'), filename)
Upvotes: 9
Views: 5897
Reputation: 1
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.
Upvotes: 0
Reputation: 5724
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
Upvotes: 3
Reputation: 16012
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.
Upvotes: 16
Reputation: 141
So you've definitely got a pure Ruby solution working, but since this is OS X, are you opposed to exec()
or system()
and just using touch
? In your case, I'd almost prefer:
system "touch -t YYYYMMDDhhmm /what/ever"
if for no other reason than clarity.
Upvotes: 3