17

I transfer files using this command

scp <localfile> user@host:<destination>

The above command only works when I'm not ssh'd into the server.

How do I transfer local files to the host machine when I'm already ssh'd in??

I ssh in using ssh user@hostname

2
  • 2
    What OS? Open up another terminal and use the scp command
    – Impulss
    Mar 8, 2013 at 23:04
  • 1
    it is centOS. Thats what I've been doing so far. I was just hoping for something more convenient. Mar 8, 2013 at 23:22

6 Answers 6

4

Nice question. scp again, but the opposite way. I did it and here it is:

chris@local ~$ ls hos*
hosts
chris@local ~$ ssh remote
Last login: Fri Mar  8 15:52:25 2013 from local
chris@remote ~$ scp chris@local:hos* .
chris@local's password: 
hosts                                              100% 1850     1.8KB/s   00:00    
chris@remote ~$ ls hos*
hosts
chris@remote ~$ 

edited to add: as pointed out in the comments, this requires that the remote computer can access the local computer. And sshd or (openssh-server) needs to be installed and running on the local machine.

2
  • 6
    This suppose the local machine is accessible from the remote one and this is not always true.
    – laurent
    Mar 9, 2013 at 0:51
  • However, if it is true it will work nicely.
    – daviewales
    Mar 9, 2013 at 4:08
4

All these "scp" answers don't answer the question IMHO.

Easiest way

You do standard I/O redirection using ssh like so

$ ssh user@host "dd if=path-of-file" | dd of=where-to-copy

You can control flow here with bs and even compress in more than 1 way:

$ ssh -C user@host "dd if=path-of-file" | dd of=where-to-copy

or something like:

$ ssh user@host "lzma -c path-of-file" | lzma -d - > where-to-copy

Another way!

For the 2nd way, let's assume you do not have root access, for some reason the first thing doesn't work, and you can't really install things on the remote host. You'll probably have python which has a built in webserver. So here's the trick.

Let's assume you are trying to get say, a file test.txt in the directory /tmp/test

$ ssh user@hostname
host$ cd /tmp/test
host$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

Now normally we can't access that because it's bound to localhost.

So we're going to break out into the SSH command shell with the escape sequence

~C

Next we're going to do SOCKS forwarding to the remote machine. Pick a higher order port, say 4321

ssh> -D 0.0.0.0:4321
Forwarding port.

Alright, leave this running. Terminal 2 time! We're going to use our port 4321 as a SOCKS proxy, which will get us to the remote machine. From there, we'll access "localhost" which will be the remote machines localhost. curl gives that to us easily.

$ curl --preproxy SOCKS://localhost:4321 http://localhost:8000/test.txt

And Yet a 3rd

You balk back at me, "I don't even have python!". Do you have bash? You probably have bash. Let's do that.

On your localhost we'll use netcat. Let's pick a port, say 5445. So Terminal 1

$ nc -lp 5445 > where-to-put-it

Terminal 2 We're going to ssh using reverse port forwarding. Also we'll just save ourselves some typing and use 0 as a collapse of 0.0.0.0.

$ ssh -R 0:5000:0:5445 user@host 'bash -c "cat path-of-file > /dev/tcp/0/5000"'   

And yet a 4th!

Alright, say you don't have scp, you don't have bash, no python, the pipe solution isn't working, GatewayPorts are disabled, jeez, you're really stuck now right?

Nonsense! base64 to the rescue! This is included in busybox, you'll find it on just about everything. Here we go!

First we establish what's called a "barrier condition". We'll use UUIDs

$ uuidgen
14184b38-5fec-41ba-a94e-0de94d5a417a

Now we're going to log in and tee the entire session to a file

$ ssh user@remote | tee /tmp/session
host> echo 14184b38-5fec-41ba-a94e-0de94d5a417a;base64 somefile;echo 14184b38-5fec-41ba-a94e-0de94d5a417a

Wait for it to flash past your session and logout.

Now we'll use our barrier conditions and a newline to extract our payload

$ cat /tmp/session |\
  sed -zE -s/'(^.*?14184b38-5fec-41ba-a94e-0de94d5a417a\r\n)(.*?)(\r\n4184b38-5fec-41ba-a94e-0de94d5a417a.*)/\2/g'

This should now just have our base64 of the file. We're almost done, just need to get rid of the newlines

$ cat /tmp/session |\
  sed -zE -s/'(^.*?14184b38-5fec-41ba-a94e-0de94d5a417a\r\n)(.*?)(\r\n4184b38-5fec-41ba-a94e-0de94d5a417a.*)/\2/g' |\
  tr -d '\r\n' |\
  base64 -d > where-to-put-it

Self-directed study

Using the last one you can do something really fun, which I'll leave as an exercise to the reader.

  1. Instead of redirecting to a file, use a fifo pipe.
  2. Create a small shell function to do the barrier condition thing above and add a way to include the filename, we'll call it sz.
  3. Create a parser that reads the fifo pipe, looks for the barrier conditions in real time, extracts the payloads and saves them disk, let's call it rz

So you'll have this.

$ mkfifo something
$ rz something &
$ ssh user@localhost | tee something
host> sz() {
 ...
}
host> sz file1
host> sz file2

This flow (and even the names) is based on modem transfer protocols like zmodem

3
  • This level of freakiness is why I love Unix systems. Thank you for this writeup!
    – Ti Strga
    May 15, 2022 at 18:47
  • Pretty impressive dude.
    – Fattie
    Aug 16, 2022 at 19:17
  • I always wondered how lrzsz worked. Thanks for the masterclass!
    – rat
    Oct 21, 2022 at 1:11
2

It would help to know what you're running on the host machine. If you're using Linux,

scp user@host:/path/myfile .

should work.

4
  • user@host is the remote machine from what I understood on Question so this command will not copy files from the local machine to the remote one but from the remote to the local if not SSHed in the host and will copy from the remote to itself if SSHed.
    – laurent
    Mar 9, 2013 at 0:54
  • I think there is some ambiguity in the question. To me, user@host appears to refer to whichever computer you are not currently controlling. So, when the OP is not logged into the remote computer, then user@host is the remote computer. When the OP is logged into the remote computer, then user@host is the local computer. If my assumptions are correct, then this answer makes sense.
    – daviewales
    Mar 9, 2013 at 4:14
  • That's exactly how I interpreted the question as well, daviewales. Also, you are correct, user@host would represent whatever workstation your're currently NOT working from, in my opinion. I debated on whether to make that more clear in my response, but figured it would be implied.
    – Josh
    Mar 9, 2013 at 4:20
  • Anyways, even if user@host represents the local machine when the user is logged on the remote machine (unlikely as the OP said he wants to transfer local files to host machine), this will work only if the local machine is accessible from the remote on (usually if they are in same LAN) and not in a scenario where the remote machine is on the internet and the local machine has no fixed IP.
    – laurent
    Mar 9, 2013 at 14:56
0

If you have a way back to your local machine (your local machine is accessible from the remote one - usually when both machines are in same LAN), using scp from the remote machine should work (scp local:/path-to-file .).

If your local machine cannot be reached from the remote one (usually true if your remote is a VPS on the internet and your local machine has a dynamic IP), your best way is to open a new terminal on local machine and copy the file.

Another way, more complicated and certainly not necessary only to copy file would be to make a VPN between the machines (or networks) so both machines would be reachable from the other and you could use scp from one machine or from the other.

0

user535759 is on the money. For me the last solution is the right one: install lrzsz on both machines (already a common package) and then use zssh to connect.

I'm too lazy to ever remember to use zssh, but once i had to connect to a host that could only accept one connection, and it was a must. Works fine.

-2

while logged into remote system(easier to just cd into file location) sudo scp file_location/file_name user@host:file_location

while logged out of remote system sudo scp authoried_user@hostname:file_location/file_name new_location_on_local_machine

FOOTNOTE: remember, while logged out of remote systems, if its a new terminal, the first password will be sudo password, 2nd password will be authorized user password. if you've sudo-ed before in that particular terminal, then its just the authorized user password u need. watch for these, it makes it tricky.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .