Instead, do (assuming GNU tools):
find . ! -name . -prune -type d -printf '@%T@\0%p\0' > time_old.list
And to restore:
xargs -t -a time_old.list -r0 -n2 touch -md
If you're using printf %q
, you need to interpret the result as shell code. That could be:
find . ! -name . -prune -type d -printf 'touch -md @%T@ ' \
-exec printf '%q\n' {} \; > time_old.bash
And:
bash -v ./time_old.bash
To restore.
But you need a standalone printf
utility that supports that non-standard %q
, and it to quote the file path in a format that is compatible with the shell language. If that's not guaranteed, that can become dangerous. That's also going to be a lot less efficient as you're forking and executing one process per directory (also the case with your GNU stat
approach). I would not have code generated from external input interpreted by a shell if that can be avoided.
Also note that touch
doesn't write anything on stdout, so the output=$(touch...)
is pointless.
Here, you could also use zsh
which has a safe quoting operator (using single-quotes which should be safe regardless of what character or non-character file names contain and be compatible with any sh-like shell (except yash)) and has a builtin stat
(which actually predates GNU stat
) so you don't have to rely on GNUisms.
zmodload zsh/stat
{
for d (*(ND/))
stat -A t -F @%s.%9. +mtime -- "$d" &&
print -r touch -d $t -- ${(qq)d}
} > time_old.sh
And restore with sh -v ./time_old.sh
.
touch -r original backupfile
, do some work, and then restore withtouch -r backupfile original; rm backupfile
. That's easier and does not require parsing anything. – Kusalananda Apr 26 '22 at 12:08