I am using scp to copy a directory from one remote server to a new directory (IE just changing the name) on another remote server like:

scp -prq server1:dir1 server2:dir2

This works fine if dir2 does not exist on server2, it creates a new directory called dir2 which contains everything from dir1 on server1.

The problem comes when dir2 already exists on server2 (NOTE: I have no way of knowing this in advance or of doing a remove on dir2 on server2 beforehand) - what happens is I get a copy of dir1, called dir1, in dir2.

I am sure there is something basic I am missing, but I just cannot seem to work it out.

Any help much appreciated!



Okay, I have less than 10 rep and cannot be ar$ed to wait 8 hrs so here is what I got:

Here is a script that works for me:

echo "method 1"
scp -prq server1:dir1/* server2:dir2/ >/dev/null  2>&1

if [ "$?" -ne "0" ]; then
        echo "failed ... trying method 2"
        scp -prq server1:dir1 server2:dir2


Still not sure how to do this in a single command or even if possible.

Cheers @mindthemonkey, sometimes just getting a fresh viewpoint can help point the way.

  • you have scp access but not ssh? – Matt Sep 12 '13 at 12:54
  • That is correct – Giles Sep 12 '13 at 13:13
  • The only problem there is you will try the second copy on any failure, which is not necessarily dir2 not existing. Maybe if you can come up with a test that does virtually nothing (say copy a blank dir). Then based on the output either run scp1 or scp2 – Matt Sep 12 '13 at 13:50
  • Good point, I`ll keep that in mind going forward and repost if I come up with something. – Giles Sep 12 '13 at 14:02
  • Can you sftp? then check the output of a cd dir2. – Matt Sep 12 '13 at 14:13

Use this "dot" syntax:

scp -prq server1:dir1/. server2:dir2/

This copies the contents of that directory, rather than the directory itself. And I believe it's more portable than * globbing.

| improve this answer | |
  • 3
    -p ⇒"Preserves modification times, access times, and modes from the original file." -r ⇒ "Recursively copy entire directories." -q ⇒ "Disables the progress meter." Source: computerhope.com/unix/scp.htm – kr85 Mar 16 '18 at 3:41
  • 9
    This gives me an error: scp: error: unexpected filename: . – Andrew Koster Apr 27 '19 at 22:53

Normally to control directory creation you need to use a trailing / to imply a complete path but I think this will then fail to create the directory if it doesn't exist:

scp -prq server1:dir1/* server2:dir2/

This could also miss hidden . files due to the * glob expansion (without some tricky shell specific work)

You can approach it differently with ssh and tar.

ssh server1 "cd dir1 && tar -cf - ." | ssh server2 "( mkdir -p dir2; cd dir2 && tar -xf - )"

But this means traffic goes via your local machine.

| improve this answer | |
  • scp -prq server1:dir1/* server2:dir2/ – Giles Sep 12 '13 at 12:54
  • @Giles are you saying that does work? – Matt Sep 12 '13 at 13:00
  • 1
    Odd, I edited that but it has got lost - no,that does not work, if the dir does not exist then scp gives an error. Also I do not have ssh available in this particular case (issue with user rights). This does give me an idea though, as I am doing this in a script I can try the above, capture any error and, on error, try the basic version from my first post. Thanks for the help @mindthemonkey – Giles Sep 12 '13 at 13:12
  • 1
    It errors 'Is a directory' when the destination directory doesn't exist for me. – Matt Sep 12 '13 at 13:16
  • 1
    Yes, me too, kind of an odd error given the directory does not exist. – Giles Sep 12 '13 at 13:31

purge it using ssh first and then recreate it with scp. i.e. in a script file...

ssh -i ~/.ssh/[private_key] user@server2 "rm -rf dir2; exit;"

scp -prq server1:dir1 server2:dir2

| improve this answer | |

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.