40

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.

Here is a script that works for me:

#!/bin/sh
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 fi

exit

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

genpfault
  • 117
Giles
  • 401

4 Answers4

43

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.

2

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.

Matt
  • 1,559
0

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

Fabze
  • 1
0

I've banged my head against exactly this same issue, and what I ended up doing was semi-punting: if dir2 is [STUFF]/parent/child2, I rename or copy or link dir1 (as appropriate for the situation) to dir1_child2 on server1 so that its last path component is also child2, and then just execute

scp -prq server1:dir1_child2 server2:[STUFF]/parent

This runs whether or not child2 is present in dir2's parent directory, and happily replaces dir2 if it is.