CentOS mailing list <centos@centos.org> writes:
I had at one point copied a large number of files between drives and did
not use the -p and thus the timestamps were all set to the date of the copy.
I did not catch this, and deleted the source. So I 'lived' with it and
have since changed many files.
Well, yesterday I found a good backup of many of those files and I want
to restore them to their proper dates.
cp -p -u is exactly the opposite of what I want. I want to copy only if
the source files have an earlier date than the destination files.
The source files are just an old copy on another drive that I found when
cleaning up things...
SRC=/my/restored/files
DST=/the/working/tree
export SRC DST
find "$SRC" -type f -print | while read A; do [ "${A}" -ot "${DST}${A##$SRC}" ] && /bin/touch -r ${A} "${DST}${A##$SRC}"; done
Note that using this syntax, the two variables cannot be set in-place on the same command line as "find ..."; it only seems to work for me if they're exported as environment variables.
A more expanded version of the same, with commentary:
cat > fix_timestamps.sh << __EOF__
#!/bin/sh
### Scans a source directory for files, setting the dates of same-named files in a target directory
### Adam Thompson <athompson@sjsd.net> 2007-Aug-07
# Source directory - no need for trailing slash
SRC=/my/restored/files
# Target directory - no need for trailing slash
DST=/the/working/tree
# Locate all _files_ only
find "$SRC" -type f -print | ( # subshell not necessary, only here for readability
# read each line of input from the pipe into $A
while read A; do
# if's can be shortened to && most times
# Proceed only if source file is OlderThan target file
if [ "${A}" -ot "${DST}${A##$SRC}" ]; then
# Proceed only if target file exists
# Probably being paranoid, since -ot should have already failed...
if [ -f "${DST}${A##$SRC}" ]; then
# Use "touch" to reset the timestamp on the file \
# instead of re-copying the data
# "-r" == "--reference", uses the source file's \
# timestamp to set the destination file's timestamp
/bin/touch -r ${A} "${DST}${A##$SRC}"
fi
fi
done
)
__EOF__
Obviously the one-liner above is going to be marginally faster, especially on slower CPUs, but the difference should be minimal - bash isn't that much of a CPU hog.
-Adam Thompson
Divisional IT Department, St. James-Assiniboia School Division
150 Moray St., Winnipeg, MB, R3J 3A2
athompson@sjsd.net / tel: (204) 837-5886 x222 / fax: (204) 885-3178