7

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?

12

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/
  • I always forget about rsync. +1 =) – Terrance Aug 2 '17 at 16:57
  • @Terrance most of the times I forget about it myself too ;) – Ravexina Aug 2 '17 at 17:01
  • @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. – Andrew Hardiman Aug 2 '17 at 18:27
  • @case_2501 nothing that I'm aware of :/ – Ravexina Aug 2 '17 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. – Andrew Hardiman Aug 2 '17 at 18:45
1

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
~$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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