10

I can copy a directory like so:

~$ cp -r ./Desktop/ /tmp/

Similarly, if I just wanted to copy the files from within a directory, I could do so:

~$ cp -r ./Desktop/. /tmp/

Things become a little more tricky if I want to copy the source directory into a target directory, that is a sub-directory of the source. i.e. copy a directory into itself. For example:

~$ cp -r ./Desktop/ ./Desktop/sub/

Would throw the following error: cp: cannot copy a directory, './Desktop/', into itself, './Desktop/sub/'

This can be circumnavigated, somewhat, using extglob, like so:

~$ cp -r ./Desktop/!(sub) ./Desktop/sub/

However, this last command is dependent on the directory sub already existing.

How can you copy a directory into itself, in such a fashion that the command to do so creates the sub directory at the same time?

0

2 Answers 2

15

Use rsync instead of cp:

rsync -Rr ./Desktop/ ./Desktop/sub/

Let's test it out:

$ cd /tmp
$ mkdir -p Desktop/sub
$ touch Desktop/a-file
$ ls -F Desktop
a-file sub/
$ cp ./Desktop ./Desktop/sub
cp: cannot copy a directory, './Desktop', into itself, './Desktop/sub/Desktop'

However rsync will work fine:

$ rsync -Rr ./Desktop/ ./Desktop/sub/
$ ls -F Desktop/sub/
Desktop/
5
  • @Ravexina thank you. Is there a purely 'cp' way of doing this? Using rsync is a great solution, however I'm too obsessed with finding a solution using the cp utility. Aug 2, 2017 at 18:27
  • @case_2501 nothing that I'm aware of :/
    – Ravexina
    Aug 2, 2017 at 18:36
  • @Ravexina thank you. I would up vote the answer, but I do not have the reputation! I'm going to persist a little while longer. It's always good to have a couple of ways to achieve the same outcome. If nothing else becomes apparent I will accept the answer. Aug 2, 2017 at 18:45
  • @case_2501 no problem ;)
    – Ravexina
    Aug 2, 2017 at 18:49
  • @Ravexina You could mention that using rsync it will create last level destination directory if it doesn't exit. so not required to mkdir sub itself in separate Aug 4, 2017 at 17:23
3

You can always use the /tmp for a transmission. (without rsync

~$ ls
1  2  3  a  b  c  ddd  w  wow
~$ cp -r . /tmp/TEMP
~$ mv /tmp/TEMP copy_dir
~$ ls
1  2  3  a  b  c  copy_dir  ddd  w  wow
~$ ls copy_dir/
1  2  3  a  b  c  ddd  w  wow

Or, make a function:

function cpc() { cp -r . /tmp/cpc-$1 && mv /tmp/cpc-$1 .; }

Like this:

~$ function cpc() { cp -r . /tmp/cpc-$1 && mv /tmp/cpc-$1 .; }
~$ ls
1  2  3
~$ cpc hhh
~$ ls hhh
1  2  3
~$ ls
1  2  3  hhh
~$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .