I lost files by using the "mv" command and I don't know where they are!

6,017

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'
Share:
6,017
Kusalananda
Author by

Kusalananda

Updated on January 04, 2023

Comments

  • Kusalananda
    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
      Admin about 2 years
      IOW, you should have done mv rapport-tp2.md $HOME/tp2 (or equivalently mv rapport-tp2.md ~/tp2) and similarly for the rest, since you created the directory tp2 inside your home directory.
    • Admin
      Admin almost 2 years
      The only file you can "restore" is sauvegarde.sh which is now ~/Downloads/221-tp2-public-main/tp2
    • Admin
      Admin almost 2 years
      Is it wrong to be slightly amused that the one file you didn't lose is the one called "sauvegarde"?
    • Admin
      Admin almost 2 years
      Related question about unintentional overwrites when using wildcards: cp and mv using wildcards and forgetting to specify a destination directory
    • Admin
      Admin almost 2 years
      Note how you typed tp2/ when doing cd, where forcing its status to a directory is unimportant, but typed tp2 when doing mv, where it is important.
    • Admin
      Admin almost 2 years
      Just 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
    Admin almost 2 years
    And also make a habit out of a) using tab completion and b) using trailing slash in destination arguments
  • Admin
    Admin almost 2 years
    @Stéphane Thanks for the edit. I came to GNU relatively recently, after too long on Solaris.
  • Admin
    Admin almost 2 years
    I moved the off-topic discussion on the merits (or lack thereof) of making aliases to the -i versions of standard tools to chat..
  • Admin
    Admin almost 2 years
    Note (if it's not already obvious) that making tp2/ the target of mv would also have avoided data loss precisely because it makes mv 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
    Admin almost 2 years
    Also 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
    Admin almost 2 years
    That 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
    Admin almost 2 years
    Some people also like to create an alias from mv to mv -i so they can't accidentally overwrite a file with mv.
  • Admin
    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
    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
    Admin almost 2 years
    Why 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
    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
    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
    Admin almost 2 years
    You 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).