Reputation: 44344
Using utimes
, futimes
, futimens
, etc., it is possible to set the access and modification timestamps on a file.
Modification time is the last time the file data changed. Similarly, "ctime" or change time, is the last time attributes on the file, such as permissions, were changed. (Linux/POSIX maintains three timestamps: mtime and ctime, already discussed, and 'atime', or access time.)
Is there a function to set change timestamps? (Where "change" is the attribute modification or 'ctime', not modification time 'mtime'.) (I understand the cyclic nature of wanting to change the change timestamp, but think archiving software - it would be nice to restore a file exactly as it was.)
Are there any functions at all for creation timestamps? (I realize that ext2
does not support this, but I was wondering if Linux did, for those filesystems that do support it.)
If it's not possible, what is the reasoning behind it not being so?
Upvotes: 32
Views: 36840
Reputation: 87401
The script below automates running debugfs ... set_inode_field ... ctime ...
in ismail's answer for many files. It will copy ctime values from files in /media/MYUSER/MYFS/FOO/BAR
(recursively) to /media/MYUSER/MYFS2/FOO/BAR
, and umount /media/MYUSER/MYFS2
as a side effect. It will work only if the filesystem of /media/MYUSER/MYFS2
is ext2, ext3 or ext4 (because debugfs
works only for these filesystems).
mydev2="$(df /media/MYUSER/MYFS2 | perl -ne '$x = $1 if !m@^Filesystem @ and m@([^ ]+) @; END { print "$x\n" }')"
cd /media/MYUSER/MYFS
find FOO/BAR -type f | perl -ne 'chomp; my @st = lstat($_); if (@st and -f(_)) { s@"@""@g; print "set_inode_field \"/$_\" ctime \@$st[10]\n" }' >/tmp/sif.out
sudo umount /media/MYUSER/MYFS2 # Repeat until success.
sudo debugfs -w -f /tmp/sif.out /dev/"$mydev2"
It handles filenames with whitespace and special characters correctly.
It works independently of time zones. As a limitation of debugfs, its precision is seconds, it ignores anything smaller (e.g. milliseconds, microseconds, nanoseconds). Depending the version of debugfs used, it may use 32-bit timestamps, thus it works correctly with dates before 2038-01-19.
If the current user doesn't have enough read permissions for /media/MYUSER/MYFS
, then the commands above should be run as root (sudo bash
).
Upvotes: 1
Reputation: 47672
For ext2/3
and possibly for ext4
you can do this with debugfs
tool, assuming you want to change the ctime
of file /tmp/foo
which resides in disk /dev/sda1
we want to set ctime to 201001010101
which means 01 January 2010, time 01:01:
Warning: Disk must be unmounted before this operation
# Update ctime
debugfs -w -R 'set_inode_field /tmp/foo ctime 201001010101' /dev/sda1
# Drop vm cache so ctime update is reflected
echo 2 > /proc/sys/vm/drop_caches
Information taken from Command Line Kung Fu
blog.
Upvotes: 32
Reputation: 25
1) change System time
2) copy paste a file on another location.
I tried this on windows 7 and I succeed to change all three timestamps. The stat command on linux shows that all three timestamps are changed.
Upvotes: 2
Reputation: 1348
I had a similar issue, and wrote my answer here.
https://stackoverflow.com/a/17066309/391040
There are essentially two options:
Upvotes: 10
Reputation: 6791
According to http://lists.gnu.org/archive/html/coreutils/2010-08/msg00010.html ctime cannot be faked (at least it's not intended to be fakeable):
POSIX says that atime and mtime are user-settable to arbitrary times via the utimensat() family of syscalls, but that ctime must unfakeably track the current time of any action that changes a file's metadata or contents.
If you just need to change a file's ctime for some testing/debugging, bindfs might be helpful. It's a FUSE filesystem which mounts one directory into another place, and can do some transformation on the file attributes. With option --ctime-from-mtime
the ctime of each file is the same as its mtime, which you can set with touch -t
.
Upvotes: 7