I need to transfer files via ssh, but unfortunately scp and sftp are not viable, as the host I am connecting is just a "door" node that is redirecting me to a different machine available only on a private supercomputing network to which it is attached (and thus it's asking me for the password twice). For this reason, I cannot run any command on the door node.

I wonder if I can transfer files using some tool that uses the output (terminal) stream from the ssh connection.

The only alternative would be outputting the files in some handy format such as base64, copying them to clipboard and decoding them locally (and vice-versa).

I am starting to get frustrated using vim remotely. What I want to achieve is a rsync-like system in which I edit the source code of my program locally and then test it remotely, but as you can see, it is not that easy.

I might not be the only one that had this problem, so I guess that there must exists a tool that has this aim? (A solution with FUSE would be the best, but I know this may be asking too much).

  • meinit.nl/…
    – MAQ
    Mar 17, 2016 at 21:04
  • @KWubbufetowicz : I cannot do that because the files are not on the "door" node but on a different machine that the door node is redirecting me to. This after prompting me with a custom program that asks me what is the destination machine. For this reason I cannot run any command on the door node.
    – fstab
    Mar 17, 2016 at 21:06
  • What operating system does your source file lies on ? Another Linux/Unix machine or Windows ? Also, are these ASCII/Text files or binary files?
    – MelBurslan
    Mar 17, 2016 at 21:14
  • @MelBurslan : it's all Linux. The files are mostly lua code, hence not very voluminous
    – fstab
    Mar 17, 2016 at 21:16
  • 1
    Is it possible to ssh to the door node and then ssh from the door node to the target machine in two separate steps? If so, I may have a solution that works for you.
    – merlin2011
    Mar 17, 2016 at 21:31

4 Answers 4


I did not want to leave this as an answer but the comments section is gettinfg larger and you will get notification from SE to carry the conversation to a chat window.

So, hit enter a couple of times and type ~? no spaces. no nothing.

you should see something like this (or exactly like this)

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.)

at this point type ~C and you should see ssh> prompt. At this point type

ssh> !scp /path/to/some/file/on/your/local/machine user@remoteserver

since you are already authenticated, it should transfer the file over the existing connection.


Depending on how much you want to automate things, expect is an option to relay data through the bastion host and on to internal systems by "typing" things into the SSH session as a human would, only faster:

#!/usr/bin/env expect

if {[llength $argv] == 0} {
  puts stderr "Usage: $argv0 bastion internalhost localfile"
  exit 1

set basthost [lindex $argv 0]
set desthost [lindex $argv 1]
set fileup   [lindex $argv 2]

spawn ssh -a -e none -o ClearAllForwardings=yes -x $basthost

# TODO login foo here for bastion host, e.g. send the password
# if see that prompt

expect {
  # TODO handle timeout, eof, etc.

  # TODO I have no idea what your ncurses interface looks
  # like, though there's doubtless something that could
  # be matched and the appropriate input sent to it...
  -ex "$ " {
    send -- "ssh $desthost\r"
    # TODO handle subsequent login to the internal host here

Then once you have an editor or whatever open on the destination host (via appropriate send statements), feed data to it via:

set upfd [open $fileup]
while {[gets $upfd line] >= 0} {
  send -- "$line\r"

And then use more send calls to save the file, exit out, etc. Also, error handling, etc.


First thing is configuration, where you set up your host to go through the "door" or rather jumpbox. You ~/.ssh/config will look somehow like this:

Host door
  Hostname door.example.com
  User username_on_door
  # ...
Host target
  Hostname tagret.example.com
  User user_on_target
  # ...
  ProxyCommand ssh -W %h:%p door

Then you can connect with one command directly to your target system: ssh target

Then you can also transfer files back and forth with single command:

ssh taget "tar czpf - /some/important/data" | tar xzpf - -C /new/root/directory
tar cpf - /some/important/data | ssh target "tar xpf - -C /some/directory/" 

or even start sshfs on to that host:

sshfs target:/dir/ /mnt/target

Not too complicated, isn't it?

  • sshfs depends on an sftp server on the remote machine. But the first part using piped stdio is great and IMHO the best answer that does not need any other tools.
    – Seven
    Jan 28 at 15:56
  • 1
    With recent versions of the ssh client "ProxyCommand ss -W %h:%p door" could be replace with "ProxyJump door"
    – Seven
    Jan 28 at 15:59

You can try scp2 from here https://github.com/alingse/scp2

It's a stupid and slow way.

scp2 -f ./scp2/core.py -u user@IP:~/core.py

here it run two steps

1. file --> base64 --> chunk --> ssh.execute(echo "[chunk body]" >> /tmpfile)
2. ssh.execute(cat /tmpfile | tr -d '\n' |base64 -d > dest)

It really only depends on ssh.

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.