Shell – Can you tell if a file has been renamed

fileslinuxrubyscriptingshell-script

Many tools out there for syncing files aren't quite right for syncing you're home directory. Because of this, and to learn Ruby, I've been working on my own sync tool.

An issue I've encountered, which I think is in my sync tools, is what happens when the user renames a file or deletes a file. Just thinking about the first case (if the user renames it) is there a way that I can tell that this is not a new file but a file that has been renames? Maybe a unique ID of the file that I don't know about. File descriptors sounds like something to look into but I'm pretty sure that's a different concept.

Best Answer

There's no way to tell for sure whether a file has been renamed.

When a file is renamed, its inode number doesn't change. (This may not be true for “exotic” filesystems, such as network filesystems, but it's true for all “native” Unix filesystems.) However the converse is not true: if a file is deleted, a new file may be created with the same inode number. So even if you see that a file has the same inode number that another file had before, that doesn't necessarily imply that the file has been renamed.

The inode number uniquely identifies the file while it exists. That makes it suitable for detecting hard links, but not for detecting renamings.

File descriptors are associated with a specific process and are useless here.

You may consider a heuristic that if a file has the same size, modification time and inode number as before but a different name, then it means that it's been renamed. This heuristic is similar to what many synchronization tools do to detect unchanged files: same name, size and modification time.

All the tools I can think of that track file renaming do it based on the contents of the file. Unison detects renamed files if at least one of the endpoints is remote. Some modern version control systems such as git also detect renamed files.

I strongly suspect that whatever you want to do with file synchronization, between rsync, Unison and version control, it already exists.

Related Question