2

Is there a way to use scp -3 to copy a file from one remote host to another, where both use non-standard SSH ports, without configuring each host involved in ~/.ssh/config?

I've seen suggestions that -P xxxx can be used before each file argument, like this:

scp -3 -P 9000 localhost:source_file -P 9001 localhost:remote_file

But I get:

-P: No such file or directory
9001: No such file or directory

on Ubuntu 17.04.

Note that the above isn't quite as insane as it looks; both localhost ports involved are actually themselves SSH tunnels to another host.

Tom
  • 327
  • 2
  • 11

3 Answers3

2

Archemar's solution will get the data copied, just not all the rest (user, group, permissions, ACLs, symlinks). So I recommend to use tar (which could do whole trees at a time if you want):

ssh -p 9000 localhost tar cf - source_file | ssh -p 9001 localhost tar xvf -

You may add -z switch to tar to make it compress data, if that matters. You may choose any destination directory by adding -C DIRECTORY. This doesn't take care of different file names on source and destination hosts, so you might need to add `

ssh localhost -p 9001 "cd DIRECTORY; mv old new"

Another easy method would be to 'temporarily park' the data-to-copy on your localhost, but most probably you already have thought about this and discarded it.

TomTomTom
  • 611
  • 3
  • 6
1

You can't.

All you can do is run scp as remote command:

ssh -p 9000 localhost "scp source_file -P 9001 localhost:remote_file"

Or use -F option to specify an alternative configuration file if you don't want to edit ~/.ssh/config

Another trick is use sshfs:

sshfs -p 9000 localhost:/somedir /tmp/src && sshfs -p 9001 localhost:/somedir /tmp/dst && scp /tmp/src/file /tmp/dst/file && fusermount -u /tmp/src && fusermount -u /tmp/dst
  • The suggestions don't really work for me. I've got a bunch of remote hosts which are only accessible on local ports (themselves ssh tunnels) and I'm trying to write some scripts to simplify ad hoc copying files between them. The first suggestion doesn't work because the remote hosts can't see each other; I realise I should have had a `-3` in my example command (now edited). The second example involves too many mount points for a simple file copy. But the "You can't" is good to know. – Tom Sep 26 '17 at 13:02
  • In the end, I've scripted the creation of a temporary `ssh_config` and then use generated host names out of that. – Tom Sep 26 '17 at 13:02
1

I would try

ssh -p 9000 localhost cat source_file | ssh -p 9001 localhost "cat > remote_file"

this implies you can ssh. Note also that :

  • file content will come to localhost and go from localhost,
  • if file is small, you'd better copy to a temporary local location,
  • if file is big an something goes wrong you have to restart all over again.

edit: tty issue

to avoid tty/encoding issue, pipe can be named

mknod tmppipe p
scp -P 9000 localhost:startfile tmppipe &
scp -P 9001 tmppipe localhost:destfile
Archemar
  • 1,369
  • 11
  • 19
  • I like the simplicity of this suggestion. It just feels like there are corner cases I can't quite think of where it's not going to do quite the right thing; is this affected by tty character encoding issues and so on? – Tom Sep 26 '17 at 13:00
  • see edition, this should go smoothly with small ascii file, however database dump and log shipping might be an issue (file deleted on source, write hang, then restart, network freeze on either incomming or outgoing, file system full on destination, insert your favorite here). Real solution is to go directly between the two host (if possible). – Archemar Sep 26 '17 at 13:09
  • Yes; sadly, in this case, it isn't possible to copy directly from one to another. – Tom Sep 26 '17 at 15:55