4

It's hard to search for special characters on google, which is why I'm posting this here.

I recently ran (as root) a mv /tmp/folder/* /* when I meant to run mv /tmp/folder/* ./ Big mistake!

Things broke! A lot of files got mixed up and placed into strange places, none of the normal unix commands worked (ls, dir, cat, etc) and once you logged off, you couldn't ssh back in -- it would give you a prompt, but not accept the old passwords.

Running ls /* shows me that it performs ls on every directory in /. If I tried to draw a parallel, then mv should have simply moved (or copied?) the files to every directory in /. Instead, really weird things happened, and I was just curious what exactly was going on.

More info: The files in /tmp/folder had been transferred from a windows machine, and had been named file (#).txt, where (#) is a number up to two digits, with a space between file and the parenthesis. There were ~40 of these text files.

derobert
  • 109,670
M L
  • 51

3 Answers3

9

The mv command takes a list of arguments which may be files or directories. If the last argument is a directory, all the others are moved into that one.

In your case, mv /tmp/folder/* /* expands to mv <the list of files in /tmp/folder> <the list of files in />. So, as you may guess, all the files in /tmp/folders/ and all the files in / but the last were moved into the last folder listed by /* (which is probably /var).

lgeorget
  • 13,914
  • 1
    If the last file listed by /* were not a directory, nothing would have happened. – lgeorget Jun 18 '13 at 19:03
  • 1
    ... so if I had performed a touch zzz before any of this, I would have been fine? That's hilarious, rofl. – M L Jun 18 '13 at 19:27
  • 7
    @ML Yes, or if you hadn't been doing that as root. That's the real lesson to take home. – derobert Jun 18 '13 at 19:38
  • 1
    @lgeorget /var, not /var/www. Do echo /* or ls -d /* to see the list. You probably did ls without the -d, which causes ls to list the contents of each directory given as an argument. – derobert Jun 18 '13 at 19:40
  • 1
    roots and wildcards are scary things, lesson duly noted @derobert :) – M L Jun 18 '13 at 19:45
  • @derobert Ups, yes, you're right. – lgeorget Jun 18 '13 at 20:04
  • Corrected the answer. I had it right the first by I edited it when I tested ls /* to be sure. >.< – lgeorget Jun 18 '13 at 20:06
5

You're picturing mv's arguments wrong. From the man page:

SYNOPSIS  
      mv [OPTION]... SOURCE... DIRECTORY

mv takes many SOURCE arguments, but only one destination DIRECTORY. mv can't move a file to multiple destinations or it would need to copy it. Since (as you said) /* resolved to all the directories in /, all of those (except the last) would have been added to the SOURCE list, so you moved all those directories into the directory listed last on the command-line.

If you boot off a LiveCD and mount the drive, you can probably undo the damage; there will be only be one directory left in the root (probably /var), and you can move all the directories that should be in the root out of it

Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • We've already rebuilt the machine, but that's good to know! I guess the tough part is knowing what needs to stay in /var... or we could just blanket copy everything in var to the root directory... – M L Jun 18 '13 at 19:44
  • Take a look at http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard to figure out which directories should stay in /var. –  Jun 18 '13 at 19:53
0

To check what exactly mv command did, you may check it by adding echo before the command, so shell will expand all wildcards and print the result command, e.g.:

$ echo mv /tmp/folder/* /*

$ echo mv /tmp/* /*
mv /tmp/launch-4TgsLB /tmp/skl /bin /dev /etc /home /lost+found /mnt /net /opt /private /sbin /tmp /usr /var

So basically it'll move your files to the last folder in your root system, probably /var.

Read more: What mv * does?

kenorb
  • 20,988