Why does MV(1) copy objects if permission to move denied?

Does mv act as cp(1) if permission for process to move denied?

If so, isn’t it against the rule do one thing and do it well?

Asked By: rich


The short answer is that it doesn’t.

mv is defined to:

perform actions equivalent to the rename() function

rename() doesn’t copy content, it simply renames it on disk. It is a completely atomic operation that never fails partially complete.

That doesn’t tell the whole story, however. Where this effect can happen is when trying to move a file between devices: in that case, it isn’t possible to do the rename in the filesystem. To have the effect of moving, mv first copies the source to the destination, and then deletes the source. In effect, mv /mnt/a/X /mnt/b/Y is essentially equivalent to cp /mnt/a/X /mnt/b/Y && rm /mnt/a/X. That’s the only way moving files between devices could work.

When mv doesn’t have permission to delete that source file, an error will be reported, but at that point the copy has already occurred. It’s not possible to avoid that by checking the permissions in advance because of possible race conditions where the permissions change during the operation.

There’s really no way to prevent this possible eventuality, other than making it impossible to move files between devices at all. The choice to allow mv between any source and destination makes things simpler in the general case, at the expense of odd (but non-destructive) behaviour in these unusual cases.

This is also why moving a large file within a single device is so much faster than moving it to another.

Answered By: Michael Homer
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.