Copy a file back to local system with ssh
If I’m logged in to a system via SSH, is there a way to copy a file back to my local system without firing up another terminal or screen session and doing scp or something similar or without doing SSH from the remote system back to the local system?
It’s easiest if you plan in advance.
Open a master connection the first time. For subsequent connections, route slave connections through the existing master connection. In your
~/.ssh/config, set up connection sharing to happen automatically:
ControlMaster auto ControlPath ~/.ssh/control:%h:%p:%r
If you start an ssh session to the same (user, port, machine) as an existing connection, the second session will be tunneled over the first. Establishing the second connection requires no new authentication and is very fast.
So while you have your active connection, you can quickly:
- copy a file with
- mount a remote filesystem with sshfs.
On an existing connection, you can establish a reverse ssh tunnel. On the ssh command line, create a remote forwarding by passing
-R 22042:localhost:22 where 22042 is a randomly chosen number that’s different from any other port number on the remote machine. Then
ssh -p 22042 localhost on the remote machine connects you back to the source machine; you can use
scp -P 22042 foo localhost: to copy files.
You can automate this further with
RemoteForward 22042 localhost:22. The problem with this is that if you connect to the same computer with multiple instances of ssh, or if someone else is using the port, you don’t get the forwarding.
If you haven’t enabled a remote forwarding from the start, you can do it on an existing ssh session. Type Enter
-R 22042:localhost:22 Enter.
See “Escape characters” in the manual for more information.
There is also some interesting information in this Server Fault thread.
If the file is small, you can type it out and copy-paste from the terminal output. If the file contains non-printable characters, use an encoding such as base64.
remote.example.net$ base64 <myfile (copy the output)
local.example.net$ base64 -d >myfile (paste the clipboard contents) Ctrl+D
More conveniently, if you have X forwarding active, copy the file on the remote machine and paste it locally. You can pipe data in and out of
xsel. If you want to preserve the file name and metadata, copy-paste an archive.
remote.example.net$ tar -czf - myfile | xsel
local.example.net$ xsel | tar -xzf -
Those are all very complicated methods.
You can mount the remote file system on your local machine with
mkdir -p /mnt/sshfs root@IS1300:~# sshfs 192.168.1.2:/ /mnt/sshfs root@IS1300:~# umount /mnt/sshfs
Then you can copy paste the file with nautilus, gnome, konqueror, dolphin, bash or whatever.
An even simpler approach:
Open Filezilla (or your favorite ftp browser), open an ssh connection to the same site, find the file and drag it across to your local file structure. If you’re new to Filezilla, use the “site manager” feature to reconnect fast next time.
Yes, I know this is obvious to most of you (and not precisely on point), but some (like me) who found this thread searching for a terminal-only solution may have overlooked the obvious.
Use “!” to convert the file to a ASCII-representation of your file (e.g.
! uuencode myfile.bin >uuencode.dat ). Then use
! cat uuencode.dat >target.dat. After that use uudecode on the target side:
! uudecode target.dat >myfile.bin
SSH does support a few commands, via the escape character (
~ by default):
$ ~? Supported escape sequences: ~. - terminate connection (and any multiplexed sessions) ~B - send a BREAK to the remote system ~C - open a command line ~R - Request rekey (SSH protocol 2 only) ~^Z - suspend ssh ~# - list forwarded connections ~& - background ssh (when waiting for connections to terminate) ~? - this message ~~ - send the escape character by typing it twice (Note that escapes are only recognized immediately after newline.) $ ~C ssh> help Commands: -L[bind_address:]port:host:hostport Request local forward -R[bind_address:]port:host:hostport Request remote forward -D[bind_address:]port Request dynamic forward -KR[bind_address:]port Cancel remote forward !args Execute local command
!args seems to be closest to what you want. Note that you’ll need to have
PermitLocalCommand enabled in your
/etc/ssh_config file in order for the
~C commands to work (see
You can re-use the same ssh session if you set up a
ssh_config. If you do this:
$ ~C ssh> !scp file user@myserver:
you’ve technically never left the ssh session, and don’t need to re-authenticate. Probably more complicated than you’d like, but I can’t think of another easy way.
- Use ssh-xfer, a modified ssh-agent which effectively overloads an existing ssh side-channel for file-transfer use.
- Use zssh, which is effectively zmodem over ssh. If you’ve ever used rzsz this will seem very familiar.
- Reverse (
-R, for remote-to-local) or forward (
-L, for local-to-remote) ports to run file transfers over, assuming you have some file-transferring daemon listening on the other end.
But none of these are really needed, IMO. The SSH protocol supports multiple channels on a single connection, and the OpenSSH client supports multiplexing. Assuming you have
ControlPath set up (
ControlPersist is useful too),
# first connection $ ssh remote # will multiplex over the same connection the original ssh opened $ sftp remote
What I’ve found to be the best and most efficient solution is to use
On the server, you use
xclip-copyfile to copy one or more files. These files are then available on your local server. There, you can use
This bypasses the need to use
scp or have a local ssh server. I use this with cygwin for instance. The only problem is that this requires installing
xclip if you don’t already have it. Oh, and this works with binary files too.
One of the many reasons we use SecureCRT — despite preferring open source software where practical — is the ease of doing file transfers. There simply is no direct replacement in the F/OSS world.
SecureCRT started out as a pure Windows program in the mid-1990s but was ported to Mac OS X and Linux a couple of years ago.
SecureCRT has three major features for transferring files to and from a system you are SSH’d into:
The easiest to use is ZModem. When you type something like
sz file-to-downloadon the remote command line, the remote
szprogram writes out an escape sequence that tells SecureCRT to immediately start downloading
file-to-downloadto the default download directory.
A nice touch is that the download directory is customizable per session. We use this to have per-site directories on our main office file server, so we don’t have to manually sort downloaded files.
szis the “send ZModem” program, part of the
lrzszpackage. It is packaged for most Unixy systems already. If for some reason your remote system doesn’t have it installed already, and you can’t easily install a binary package, the source package is small and highly portable. More than once, I’ve had to send an
uuencode‘d tarball to a stripped-down remote system so I could ZModem files to it.)
SFTP – SecureCRT has a tightly integrated basic SFTP implementation.
By “tightly integrated,” I mean that when you give the SFTP menu command or keyboard shortcut, it opens a new tab connected to the remote site over the same SSH connection. Thus, you don’t need to log back in, and the connection is established a bit faster than if you had opened a separate SFTP connection to the same server.
I characterize the SFTP feature as “basic,” because VanDyke Software has a separate file transfer product, SecureFX. It is more featureful than the built-in SFTP client, and also integrates with SecureCRT.
SecureCRT’s SFTP feature lets you configure default remote and local directories which are separate from the ZModem configuration.
This SFTP feature has a basic command line sort of interface, mimicking OpenSSH’s
sftpprogram, except that it has affordances like Tab command completion. Thus, retrieving a remote file called
somefile.tar.gzmight be as easy as
Drag-and-drop – If you drag-and-drop a file onto the terminal window, it automatically types
rzfor you and starts sending the file.
Alternately, you can open an SFTP tab and drop a file onto that tab to send it via SFTP. Thus, sending a file to a remote system could be as simple as Alt-P, drag, drop.
We find that transfers happen a lot faster via SFTP, probably because it’s a TCP-based protocol, so it benefits from the large sliding windows of modern TCP/IP stacks. ZModem was designed in the days when a 64 kiB block size was considered “large.” Thus, a lot of the potential speed in a link is soaked up in ZModem while each end waits for block transfer acknowledgements.
One nice thing about the drag-and-drop mode of operation is that it takes one of the stresses out of using ZModem. When you type
rzat the remote system, SecureCRT pops up a file picker automatically. You then have about a minute to find and select the file before the remote side times out. This creates a race-against-the-clock vibe that isn’t pleasant. Drag-and-drop lets you find the file at your leisure, then start the transfer with a single quick motion of the mouse.
We do still use the manual method, starting the transfer with an explicit
rzcommand. This is because SecureCRT lets you configure a per-session upload directory, which we point at the folder on the file server that always contains the latest build of the software that particular remote site is running. For such transfers, there is no race against the clock, since the file picker opens in the correct place to start with.
Another (IMO) easy way would be:
# to remote host cat localfile.conf | ssh user@hostname 'cat -> /tmp/remotefile.conf' # from remote host ssh user@hostname 'cat /tmp/remotefile.conf' > /tmp/localfile.conf
If you need to jump through one (or more) proxy servers, OpenSSH v7.3 onward supports a
Considering A → B → C, on hostA, just:
tar cf - file1 file_n | pv | ssh -C -J userB@hostB:portB userB@hostC -p portC 'tar xvf - -C hostC_destination_folder'
- Use as many hops as you want with ssh’s
- Omit the tar’s remote
-Cto leave the files on home folder.
- Send any files at once (text or binary).
- Increase speed by compressing the stream with ssh’s
-z). Particularly useful if the data is plain text (uncompressed).
pvmonitor the progress of data through a pipe. An alternative could be
Here‘s how to do it with Midnight Commander.
Related project: Magic Wormhole: Get things from one computer to another, safely.