How to mv a folder in Linux retaining its mtime?

23,821

Solution 1

POSIX mv doesn't provide any option to ask for atime/mtime preservation, but as the operation is local to a same volume, you can ask cp to use hard-links instead of copying data of the regular files using the -l option:

cp -p -r -l source/date target/
rm -rf source/data

Since only directories and file references will be actually copied, it should go much faster:

For more informations on hard-links, you can consult the corresponding Wikipedia page

As for why subdirectories mtime is being reset with your current solution, it's because you only get and restore the parent directory mtime : touch is not a recursive command.

Solution 2

Another solution may be:

rsync -a --remove-source-files source/data target/

Share:
23,821

Related videos on Youtube

Roman Zenka
Author by

Roman Zenka

Updated on September 17, 2022

Comments

  • Roman Zenka
    Roman Zenka over 1 year

    I am using CentOS 5.5 and would like to move a large amount of folders within one volume, retaining their mtime.

    The best solution I could find is like this:

    cp -p -r source/data target/
    rm -rf source/data
    

    With over 1TB of data on a NFS share, the copying takes forever. I do not want to copy. I want instantaneous move.

    When I move a folder using mv source/data target/, the mtime of the folder (not the files) gets set to current time. This is because the contents of folder I am moving get modified by this operation (the .. entry is pointing to a different inode).

    I came up with a following shell script I called mv_preserve_mtime.sh:

    #!/bin/bash
    # Moves source folder to target folder. 
    # You are responsible for making sure the target does not exist, otherwise this blows up
    export timestamp=`stat -c %y $1`
    mv "$1" "$2"
    touch --date="${timestamp}" $2

    Well, that did not work either. The folder's mtime is restored, but all folders within the folder I move (only the ones 1 level deep) get their mtime reset for reasons I do not understand.

    Does anyone have a proper, efficient and correct solution?

    • Gilles 'SO- stop being evil'
      Gilles 'SO- stop being evil' over 13 years
      I wonder why your attempt with touch didn't work. Is it the mv step or the touch step that changes the mtime of the subdirectories? What OS is on the NFS server, and (if you know) what filesystem type?
    • Roman Zenka
      Roman Zenka over 13 years
      @Gilles: I do not know why is it happening. It is the mv step that causes trouble. The NFS server is actually a NetApp storage, I know virtually nothing about its internals.
    • Gilles 'SO- stop being evil'
      Gilles 'SO- stop being evil' over 13 years
      Thanks. I suspect it's a NetApp oddity. Otherwise touch should have worked. By the way a more portable way would be touch -r "$1" reference.tmp; mv -- "$1" "$2"; touch -r reference.tmp -- "$2"; rm reference.tmp.
  • Roman Zenka
    Roman Zenka over 13 years
    The mtime is more complicated than that. Only the parent directory and the directories directly under it have mtime changed. All other directories remain the same. One would expect either every single directory to be changed, or only the parent.
  • Eureka
    Eureka over 13 years
    Actually, it makes sense: 1) The parent directory has the good mtime because it was explicitly set by touch, 2) The directory entries where recreated with the parent directory, but their mtime was not manually restored (Unix directory structure and inode format) 3) The rest of the tree structure wasn't actually changed, as we remained on the same volume : That's why mv has no "recursive" option, descending into subdirectories is only done if actual copy (different volumes, for example) is needed.
  • Eureka
    Eureka over 13 years
    @Roman Zenka After some search, this behaviour seems to be rather loosely specified between Unices and filesystems and to depend a lot of the underlying rename syscall implementation by the kernel and the used filesystem(s), NFS adding its share to the problem. There are some pointer referencing this kind of inconsistencies: patchwork.ozlabs.org/patch/25833 bugs.opensolaris.org/bugdatabase/…
  • Roman Zenka
    Roman Zenka over 13 years
    @Eureka: I find it extremely hard to believe that something I would consider so basic can be such a mess. It is almost 2011. Thanks for those resources!
  • Eureka
    Eureka over 13 years
    @Roman Zenka So do I... If you ever find a definitive explanation, I'll be interested: I couldn't find it yet.
  • Lenar Hoyt
    Lenar Hoyt over 6 years
    This does not seem to work on macOS.
  • android developer
    android developer almost 6 years
    @Eureka Trying to do it on Android (because of this: stackoverflow.com/q/50540334/878126 ) I get this error : cp: /data/local/tmp/test.apk: Cross-device link . Any idea why? Is there perhaps a way to store and later restore the timestamp of the file?