vote up 2 vote down star
1

How do you copy all the contents of one directory into another?

For example:

$ cd /home/newuser
$ cp -a /backup/olduser/* .

The problem with the above is that the globing pattern '*' matches the hidden directories '.' and '..' and you end up with a directory 'olduser' inside 'newuser', as well as the contents.

You could also do something like this:

$ rmdir /home/newuser
$ cp -a /backup/olduser /home/newuser

But what if newuser already contains some default files and directories?

What is the simplest, most correct, easiest to remember and not mess-up way to move the contents of one directory to another using just the basic 'cp' command and the shell?

flag

6 Answers

vote up 10 vote down

Two directories a and b.

Both have files in.

You are in a directory that contains a and b.

cp -r ./a b

-r = recursively.

link|flag
Don't you want -a to get all files? – bill weaver Aug 20 at 17:22
3  
The -a argument is nothing do to with all files, it's short for archive, it will preserve file ownership, permissions, access times etc. The -a argument (while highly useful) isn't a standard option, and several cp implementations don't provide it. – theotherreceive Aug 21 at 3:26
Yep, the version I'm using looks like this: 'cp [-R [-H | -L | -P]] [-fi | -n] [-pvX]' with no -a option. – Rich Bradshaw Aug 21 at 9:01
What about hidden . files? – mch Nov 7 at 21:52
1  
@mch: automatically included, because you've told cp to copy a directory a, and a/.somedotfile is contained by a. if b exists, this command will create an exact copy of a at b/a. – ~quack Nov 8 at 0:33
show 1 more comment
vote up 3 vote down

Unless you have seriously reconfigured your shell, the globbing pattern '*' does not match '.' or '..', as you can verify using just echo *. What it does instead do is omit files whose name begins with a '.', so your approach will miss all hidden files. You can tweak some of this behavior with shell options, for example the dotglob option in bash, but it then won't be the portable and robust option that you are looking for.

If you need to do this more than once or twice, I recommend that you look into rsync or unison (depending on specific needs) with carefully crafted source and target specifications.

Another alternative is to put the source directory in a tarball and untar it over the existing target directory.

link|flag
i use this: ( cd /src/dir ; tar cf - . ) | ( cd /dest/dir ; tar xf - ) ... the tar cf - . tar's the source directory, dotfiles included, and spits it to STDOUT, which gets piped to the STDIN of the tar xf -. – ~quack Nov 8 at 0:37
vote up 2 vote down

Try:

cp -ra /backup/olduser/. /home/newuser
link|flag
vote up 0 vote down

To copy files that begins with a dot just do cp .* target/

So easiest is just to do the cp command two times.

As Peter Eisentraut sais normal globbing rules do not include .. and . (hm, how to end this sentence? ;)

Just use -r to make it recursive and -i to make cp ask whether you really want to overwrite a file.

cp -ri /backup/olduser/* /newuser/
cp -ri /backup/olduser/.* /newuser/
link|flag
Usually * does not match . or .., but it does if you use .*. Try echo .*. You can exclude . and .. with the following pattern: .[^.]*. – mch Nov 7 at 21:52
vote up 0 vote down

Also remember that by default cp copy the first directory INTO the second directory if the second exists. For example cp -a a b will copy a INTO b if b exists, i.e. it will create a into b.

If it's not what you want, and you want to copy the content of a into b (for example when copying a whole filesystem into a mount point) use:

cp -a a/. b

as in the previous answer.

Please also note that -a includes -r so -ar is redundant.

link|flag
vote up 0 vote down

This will copy both the normal and hidden files, while excluding the parent directory (..):

cd /directory/to/copy
cp -r * .[^.]* /destination/directory

If you do not exclude the parent directory, you end up with all of the contents of .. in your destination directory as well.

link|flag

Your Answer

Get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.