How mv
works
Below there are excerpts from the POSIX specification of mv
and my comments.
SYNOPSIS
mv [-if] source_file target_file
mv [-if] source_file... target_dir
You may have used non-POSIX options; irrelevant. I'm citing the synopsis here because the later citations mention source_file
and it's good to know what exactly they mean. Note a directory is also a file.
[…]
For each source_file
the following steps shall be taken:
[…]
The mv
utility shall perform actions equivalent to the rename()
function […]
[…]
If this succeeds, mv
shall do nothing more with the current source_file
and go on to any remaining source_file
s. If this fails for any reasons other than those described for the errno
[EXDEV
] […], mv
shall write a diagnostic message to standard error, do nothing more with the current source_file
, and go on to any remaining source_file
s.
This basically means mv
tries to rename
the source_file
first. Inside a single filesystem this (usually, not always (example)) works and then mv
doesn't need to do anything more. EXDEV
means this cannot work and then mv
tries a different approach. In your case the fact the old directory is still there along with the (partial) new directory means rename
threw EXDEV
and mv
tried the different approach. The main point of the different approach is as follows:
[…]
The file hierarchy rooted in source_file
shall be duplicated as a file hierarchy rooted in the destination path. […]
[…]
If the duplication of the file hierarchy fails for any reason, mv
shall write a diagnostic message to standard error, do nothing more with the current source_file
, and go on to any remaining source_file
s.
If the duplication of the file characteristics fails for any reason, mv
shall write a diagnostic message to standard error, but this failure shall not cause mv
to modify its exit status.
So mv
acts similarly to cp -Rp
. If there is any problem with duplicating data (but not characteristics, metadata) then it doesn't proceed to the next step, which is:
- The file hierarchy rooted in
source_file
shall be removed.
So after successfully doing the cp
part at least for data, mv
acts like rm -r
for the current source_file
before proceeding to the next (if any).
The conclusion is: if your mv
follows the POSIX specification (e.g. GNU mv
basically should) and if you specified a single source_file
(it seems so) and if the error prevented any data from being duplicated (it seems so) then everything you tried to move should stay intact in the source location.
But see the caveats below.
Caveats
If the error you observed was from step 7 (as opposed to step 6) then the source location may or may not be intact. E.g. imagine your mv
was not allowed to remove anything; or maybe it was not allowed to remove the directory in question from /home/data
after removing everything from the directory itself. Unfortunately you did not tell us the exact error(s) you observed. Note any error from step 7 means step 6 has already duplicated the data successfully (if it didn't, step 7 would be skipped). If the destination is obviously missing some files, the error was probably from step 6 and the removal of the source location was not tried in the first place.
In the context of your question there is a huge difference between
mv foo /destination/
and
mv foo/* /destination/foo/
In the former command there is exactly one source_file
, step 6 is performed at most once and step 7 is performed at most once. If foo
is not replicated in the destination
then nothing will be deleted. In the latter command foo/*
is expanded by the shell to possibly many source_file
s and mv
processes each one separately; so if step 6 fails and this is going to suppress step 7 then it will suppress step 7 for the currently processed source_file
only.
Unfortunately you did not tell us the exact command you used. You wrote "the folder was still created" and I interpret this as "created by mv
". The latter of the two commands requires /destination/foo/
to exist beforehand, so I conclude your command was not like it and this caveat is not relevant to your particular case.
Your explicit questions
How to check what was moved when using mv
and the process stops due to permissions issues?
In general: by carefully examining what's in the target location and what's missing in the source location. It's way easier if the source location was initially empty. As explained above, if you specified exactly one source_file
and the error was from the copying phase (step 6), not from the deleting phase (step 7), then probably you don't need to check anything, the source is intact.
Is it correct to conclude that nothing has been moved when the source test folder has not been changed today?
In general it depends on what you mean by "the source test folder has not been changed today". If you judge solely by mtime
of this single directory or/and files directly in it, then the important fact is mtime
does not propagate from a file to its parent directory and further. If a file deep in the directory tree changes then you won't know unless you examine things deep enough.
Still in your case you probably don't need to check anything, the source is intact. If you're not sure, see how to get "recursive" last modified date for a directory. Removing a file from its directory changes the mtime
of the directory, so this is a right way to check if your mv
may have removed anything.
Why is it [the output from du -sh
] not zero?
Because there are files in the directory. ls -la
confirmed this.
ls -la
shows .profile
, .ssh
, .vnc
and .config
as well as the links to the folders up the tree. Does that mean that those are only "hidden files" and this is where the non zero size comes from?
Yes. Use du -ah
to confirm this.
du -ah /path/to/allegedly_empty_dir
? Or at leastls -la /path/to/allegedly_empty_dir
? Please edit the question and add this information.