I lost files by using the "mv" command and I don't know where they are!
Solution 1
You created a directory called tp2
in your home directory, i.e. you created the directory ~/tp2
. You then changed into ~/Downloads/221-tp2-public-main
and started to move files with mv
.
Since you specified the target of each mv
operation as tp2
, and since tp2
was not a directory in your current directory, each file you moved was instead renamed tp2
. You overwrote the file previously called tp2
each subsequent time you ran mv
. In the end, the tp2
that you were left with is the file previously called sauvegarde.sh
.
You would have avoided the loss of data by using ~/tp2/
as the target of each mv
operation.
The ~
refers to your home directory, where you created your tp2
directory. The /
at the end of the target path is not strictly necessary, but it makes mv
fail gracefully if ~/tp2
is not a directory.
As for what you can do now to restore your lost files; consider restoring them from a recent backup if you don't have other copies of them lying around elsewhere.
Solution 2
The GNU implementation of the mv
command (the one found on Ubuntu) has an explicit mv -t myDir
option that checks that myDir
is specifically an existing directory. This avoids the ambiguity between mv Source Dest
(move to) and mv Source Directory
(move into).
It also fixes the args order in constructs like find ... -print0 | xargs -r0 mv -t Dir --
, where xargs by default appends args (so that placing the target directory last is not possible). Both these cases would have avoided your issue.
The mv -i
option also offers protection against overwriting files accidentally.
Solution 3
Avoid doing this, interactively:
mv file1 dest
mv file2 dest
mv file3 dest
At least, avoid issuing multiple commands like this without checking the result of the first one:
mv file1 dest
ls -l dest # is there a dest, containing file1?
Instead, combine them into one:
mv file1 file2 file3 ... dest
If there are two or more files, then dest
is interpreted as necessarily having to be a directory which exists. If it doesn't exist or isn't a directory, then mv
fails:
mv: target 'dfsafsdfdf' is not a directory
If you issue multiple commands without checking their results, you may lose the benefit of whatever few safeguards they provide.
mv
has a POSIX_standard -i
option to avoid clobbering a destination which exists. You can include that in your interactive mv
command via making an alias:
alias mv='mv -i'
Kusalananda
Updated on January 04, 2023Comments
-
Kusalananda over 1 year
I lost some files by using the
mv
command. I don't know where they are. They are not in the directory to which I intended to copy them.Below is a transcript of what I did:
samuelcayo@CAYS07019906:~/Downloads/221-tp2-public-main$ cd samuelcayo@CAYS07019906:~$ ls Desktop Documents Downloads GameShell Music Pictures pratice Public Templates Videos samuelcayo@CAYS07019906:~$ mkdir tp2 samuelcayo@CAYS07019906:~$ ls Desktop Documents Downloads GameShell Music Pictures pratice Public Templates tp2 Videos samuelcayo@CAYS07019906:~$ cd Downloads/221-tp2-public-main/ samuelcayo@CAYS07019906:~/Downloads/221-tp2-public-main$ ls backup copybash Dockerfile ntfy-1.16.0 packets.txt README.md restore secret cloud data Dockerfile_CAYS07019906 ntfy.zip rapport-tp2.md remplacer.sed sauvegarde.sh tail samuelcayo@CAYS07019906:~/Downloads/221-tp2-public-main$ mv rapport-tp2.md tp2 samuelcayo@CAYS07019906:~/Downloads/221-tp2-public-main$ mv Dockerfile_CAYS07019906 tp2 samuelcayo@CAYS07019906:~/Downloads/221-tp2-public-main$ mv packets.txt tp2 samuelcayo@CAYS07019906:~/Downloads/221-tp2-public-main$ mv sauvegarde.sh tp2 samuelcayo@CAYS07019906:~/Downloads/221-tp2-public-main$ cd samuelcayo@CAYS07019906:~$ cd tp2/ samuelcayo@CAYS07019906:~/tp2$ ls samuelcayo@CAYS07019906:~/tp2$ ls -l total 0 samuelcayo@CAYS07019906:~/tp2$ cd ..
-
Admin about 2 yearsIOW, you should have done
mv rapport-tp2.md $HOME/tp2
(or equivalentlymv rapport-tp2.md ~/tp2
) and similarly for the rest, since you created the directorytp2
inside your home directory. -
Admin almost 2 yearsThe only file you can "restore" is
sauvegarde.sh
which is now~/Downloads/221-tp2-public-main/tp2
-
Admin almost 2 yearsIs it wrong to be slightly amused that the one file you didn't lose is the one called "sauvegarde"?
-
Admin almost 2 yearsRelated question about unintentional overwrites when using wildcards: cp and mv using wildcards and forgetting to specify a destination directory
-
Admin almost 2 yearsNote how you typed
tp2/
when doing cd, where forcing its status to a directory is unimportant, but typedtp2
when doing mv, where it is important. -
Admin almost 2 yearsJust for the record, this is exactly what source control can help you with. Just restore from the history. You may want to learn
git
.
-
-
Admin almost 2 yearsAnd also make a habit out of a) using tab completion and b) using trailing slash in destination arguments
-
Admin almost 2 years@Stéphane Thanks for the edit. I came to GNU relatively recently, after too long on Solaris.
-
Admin almost 2 yearsI moved the off-topic discussion on the merits (or lack thereof) of making aliases to the
-i
versions of standard tools to chat.. -
Admin almost 2 yearsNote (if it's not already obvious) that making
tp2/
the target ofmv
would also have avoided data loss precisely because it makesmv
fail. Either get the directory right, or put/
on the end, or both. Since you can't be sure you'll always get the directory right, but you can decide to always put/
on the end, you should decide to always put/
on the end. -
Admin almost 2 yearsAlso a good habit could be to use the tab-completion. When you notice that the target was not completed to
tp2/
you notice that something is wrong - the target directory does not exist. -
Admin almost 2 yearsThat is why it is a good idea to use alias on mv, cp so that they are really mv -i, cp -i etc to avoid accidents like this.
-
Admin almost 2 yearsSome people also like to create an alias from
mv
tomv -i
so they can't accidentally overwrite a file withmv
. -
Admin almost 2 years@stackoverblown I take the opposite view. I spent 15 years on customer sites working for a mainframe manufacturer, and then 30+ years as a contractor. Having basic commands configured to suit the personal prejudices of some cowboy SysAdmin is my idea of hell.
-
Admin almost 2 years@Paul_Pedant reminds me of one server I used where every text editor was linked to the sysadmin's (weird) personal favorite editor.
-
Admin almost 2 yearsWhy the hostility against alias mv='mv -i' ? OP appears to be an end-user, not a sysadmin (cowboy or other), so an alias isn't going to mess up scripts or settings that are shared with others. It's good for average users to have some protection against accidents.
-
Admin almost 2 years@AlexanderHanysz When I am troubleshooting at a client with 100s of workstations, I need them all to work as standard. See my previous comment (with upvotes), and the chat referred to by @terdon. One example: make your alias, get used to having it, and then sudo so you can get extra permissions to
mv
some files. Just when you need it most, your "safer" alias does not exist in that environment ! -
Admin almost 2 years@Paul_Pedant But then one could have set alias sudo='sudo '. Voila! I understand your point of view how aliases make life difficult for you. But without them, users and cowboy admins could too easily get into trouble like the OP.
-
Admin almost 2 yearsYou should probably explain that the alias is dangerous, because it encourages a dependency on it, making errors more likely when it's not available (e.g. in a
sudo
shell).