Is there a quick way of copying files "up" an SSH connection?
June 2, 2008 6:56 AM   Subscribe

Is there a quick way of copying files "up" an SSH connection?

Say I'm logged into a remote machine and have navigated to some inconveniently deep location in the directory structure, where I find a file I want to copy back to the local machine from which I established the SSH connection.

However, the local machine is not visible from the public internet so I either have to set up a port forward on the router it lies behind (and perhaps a DynDNS alias) and scp from the remote machine, or log out/start a new terminal on the local machine and issue an scp command from there, referring to the aforementioned inconveniently deep location of the file.

It seems like there should be a more ad hoc, easier way to copy a file back up an SSH connection. Is there?
posted by caek to Computers & Internet (14 answers total) 7 users marked this as a favorite
 
I just use scp from the local machine for this kind of thing (copy/paste are my friend for long paths)...

Having said that, if you've got sshd running on your local machine, you could set up a port forward when you establish your ssh connection (e.g. map remote port 5000 to local sshd port) so when you find a file you want to copy, just use scp -P 5000 yourfile localhost:/pathonlocalmachine.

Be warned that tunneling SSH over SSH has generally sucky performance. If you've got an FTP server running locally the same trick would work (forward a remote port to your local ftp port) and you can just use something like ncftp to copy files in an ad-hoc fashion.

If you're feeling brave, try setting up an nfs/samba mount over the tunnel instead so you can just copy files to a mounted NFS path on the remote machine and have them magically appear locally.
posted by tkbarbarian at 7:09 AM on June 2, 2008


Zmodem.

rzsz on *nix based systems.
posted by unixrat at 7:12 AM on June 2, 2008


Ack, wrong link.

RZ/SZ have been the Zmodem implementations that I've used over SSH.

R = receive, S = send.

So if you want to send a file to a remote machine, you fire up rz on the remote side and use your term's sz to send the file. Vice versa for receiving files.

1986 represent!
posted by unixrat at 7:16 AM on June 2, 2008 [1 favorite]


As long as I'm thinking about it, I might as well keep writing...

Zmodem supported error checking, resuming interrupted sessions, multiple file transfers, and a few other nice things. It's a perfectly cromulent transfer protocol, perfect for the situations that you've described - i.e. pulling a file 'directly from the terminal'.
posted by unixrat at 7:27 AM on June 2, 2008


Seconding unixrat. Zmodem is a godsend. WHen I first transferred a file via Zmodem over an ssh session, I was shocked and amazed; I hadn't used Zmodem since my old BBS days!

Also, if you are connecting fom a WIndows system, there are a bunch of different term. emulators that have built in x/y/zmodem support (I used TeraTerm for years before moving to full *nix).
posted by Cat Pie Hurts at 7:35 AM on June 2, 2008


ZSSH is SSH with Zmodem file transfer capability wrapped in.
posted by Eater at 7:36 AM on June 2, 2008


Filezilla is an FTP program that lets you connect over SSH. Maybe not what you're looking for, but certainly useful for file transfers when FTP isn't an option.
posted by lubujackson at 7:57 AM on June 2, 2008


The sftp command in another tab. Just highlight the pwd and cd to that directory.
posted by a robot made out of meat at 9:01 AM on June 2, 2008 [1 favorite]


Best answer: I found I had to do this all the time created a couple of scripts do this. It works somewhat like the Windows Explorer file clipboard capability. Run the pickup command on the file you are interested in remotely. Then run dropoff remotehost locally, and it will be copied to your current directory, inconveniently long pathname and all.

Do this on both systems in a directory that is in your PATH, such as ~/bin:
cat > dropoff <> #!/usr/bin/env bash

# examples:
# dropoff
# ~/.pickup/* -> .

# dropoff server
# server:~/.pickup/* -> .

# dropoff server target
# server:~/.pickup/* -> target

_PICKUPDIR="~/.pickup"

if [ $1 ]; then
  scp -r "${1}:${_PICKUPDIR}/*" "${2:-.}"
else
  cp --dereference -prv "${_PICKUPDIR}/*" .
fi
EOF

cat > pickup <> #!/usr/bin/env bash

_PICKUPDIR="~/.pickup"

rm -r ${_PICKUPDIR}
mkdir -p ${_PICKUPDIR}
for FILENAME in "$@"; do
  ln -sfv "${PWD}/${FILENAME}" ${_PICKUPDIR}
done
EOF

cat > dropoff <>
posted by grouse at 9:06 AM on June 2, 2008 [1 favorite]


Crap. MetaFilter ate my code. Download the scripts from here instead:
posted by grouse at 9:09 AM on June 2, 2008


I'm probably doing this the completely wrong way and am somehow enraging sysadmins everywhere, but what I typically do is mount, via sshfs, the remote machine to the local machine. From there, navigating (and hence copying) the remote machine is trival while on the local machine.

How to mount a remote ssh filesystem using sshfs.
posted by cgg at 9:43 AM on June 2, 2008


I have
# Let myself connect back in:
RemoteForward 2217 localhost:22
in my laptop's .ssh/config, and
Host mylaptop
User ft
HostName localhost
Port 2217
in the .ssh/config of machines I use regularly. This lets me just rsync file mylaptop: on the remote machine.
posted by fantabulous timewaster at 10:24 AM on June 2, 2008


ssh has a "proxy command" which can be used to let you 'ssh inner' (and sftp inner, and lftp fish://inner) even if 'inner' can only be connected by going through 'outer'. 'nc' (aka netcat) is a Free, small and widely available program which simply creates a tcp connection to the given host and port. Here's a ~/.ssh/config entry showing how to use nc in this way:
host inner
ProxyCommand ssh outer nc inner %p
Protocol 2
ForwardAgent yes
I quite simply can't do without this functionality; I must use it a hundred times a day.
posted by jepler at 12:05 PM on June 2, 2008 [1 favorite]


jepler, you've helped me to finally understand the proxycommand syntax. Thanks! I have several machines that I access through one tunnel, and now that I've added
Host outer
LocalForward 2244 inner1:22
LocalForward 2245 inner2:22
...

Host inner1
HostName localhost
Port 2244
ProxyCommand /bin/bash -c ' echo | nc -w1 %h %p >& /dev/null || ssh outer -f exit && nc -w1 %h %p '
to my .ssh/config I no longer have to futz about with checking whether the tunnel is open already or not. Thanks!
posted by fantabulous timewaster at 11:26 AM on June 3, 2008


« Older Generic books (titled as such)   |   The Ghost in my Wife's Samsung Mobile Newer »
This thread is closed to new comments.