我使用此命令传输文件
scp <localfile> user@host:<destination>
仅当我未通过 ssh 进入服务器时,上述命令才有效。
当我已经通过 ssh 登录时,如何将本地文件传输到主机?
我正在使用 sshssh user@hostname
答案1
好问题。scp
再次,但方法相反。我这样做了,结果如下:
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 ~$
编辑并添加:正如评论中指出的那样,这需要远程计算机能够访问本地计算机。并且需要在本地计算机上安装并运行 sshd 或 (openssh-server)。
答案2
在我看来,所有这些“scp”答案都没有回答这个问题。
最简单的方法
你可以使用 ssh 进行标准 I/O 重定向,如下所示
$ ssh user@host "dd if=path-of-file" | dd of=where-to-copy
bs
您可以在此处使用多种方式控制流量甚至进行压缩:
$ ssh -C user@host "dd if=path-of-file" | dd of=where-to-copy
或者类似的东西:
$ ssh user@host "lzma -c path-of-file" | lzma -d - > where-to-copy
其他方式!
对于第二种方法,我们假设你没有 root 权限,由于某种原因第一种方法不起作用,你无法在远程主机上真正安装东西。你将大概有内置 web 服务器的 python。所以这里有个窍门。
test.txt
假设你正在尝试获取目录中的文件/tmp/test
$ ssh -o EnableEscapeCommandline=yes user@hostname
host$ cd /tmp/test
host$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
现在通常我们无法访问它,因为它已绑定到本地主机。
因此,我们将使用转义序列进入 SSH 命令 shell
~C
接下来,我们将对远程机器进行 SOCKS 转发。选择一个更高级别的端口,例如 4321
ssh> -D 0.0.0.0:4321
Forwarding port.
好的,让它继续运行。终端 2 时间到了!我们将使用端口 4321 作为 SOCKS 代理,这将带我们到达远程计算机。从那里,我们将访问“localhost”,它将是远程计算机的 localhost。curl 可以轻松将其提供给我们。
$ curl --preproxy SOCKS://localhost:4321 http://localhost:8000/test.txt
还有第三个
你回头对我说:“我甚至没有 Python!”你有 Bash 吗?你可能有 Bash。让我们这样做吧。
在您的本地主机上,我们将使用 netcat。让我们选择一个端口,例如 5445。因此终端 1
$ nc -lp 5445 > where-to-put-it
终端 2 我们将使用反向端口转发来访问 ssh。此外,我们只需省去一些输入,并使用 0 作为 的折叠0.0.0.0
。
$ ssh -R 0:5000:0:5445 user@host 'bash -c "cat path-of-file > /dev/tcp/0/5000"'
还有第四个!
好吧,假设您没有 scp,没有 bash,没有 python,管道解决方案不起作用,GatewayPorts 被禁用,天哪,您现在真的陷入困境了,对吧?
废话!base64 来救场了!它包含在 busybox 中,您几乎可以在所有东西上找到它。开始吧!
首先,我们建立所谓的“障碍条件”。我们将使用 UUID
$ uuidgen
14184b38-5fec-41ba-a94e-0de94d5a417a
现在我们要登录并将整个会话发送到一个文件
$ ssh user@remote | tee /tmp/session
host> echo 14184b38-5fec-41ba-a94e-0de94d5a417a;base64 somefile;echo 14184b38-5fec-41ba-a94e-0de94d5a417a
等待它闪过您的会话并注销。
现在我们将使用屏障条件和换行符来提取有效载荷
$ cat /tmp/session |\
sed -zE -s/'(^.*?14184b38-5fec-41ba-a94e-0de94d5a417a\r\n)(.*?)(\r\n4184b38-5fec-41ba-a94e-0de94d5a417a.*)/\2/g'
现在应该只剩下文件的 base64 编码了。我们快完成了,只需要删除换行符
$ 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
自主学习
使用最后一个,你可以做一些非常有趣的事情,我会把它作为练习留给读者。
- 不要重定向到文件,而是使用
fifo
管道。 - 创建一个小型 shell 函数来执行上面的屏障条件,并添加一种包含文件名的方法,我们将其称为
sz
。 - 创建一个解析器,读取 fifo 管道,实时查找屏障条件,提取有效载荷并保存在磁盘上,我们称之为
rz
所以你会拥有这个。
$ mkfifo something
$ rz something &
$ ssh user@localhost | tee something
host> sz() {
...
}
host> sz file1
host> sz file2
此流程(甚至名称)基于调制解调器传输协议,例如调制解调器
答案3
了解主机上运行的程序会有所帮助。如果你使用的是 Linux,
scp user@host:/path/myfile .
应该管用。
答案4
user535759 说得对。对我来说,最后一种解决方案是正确的:在两台机器上安装 lrzsz(已经是一个通用包),然后使用噓连接。
我太懒了,从来不记得使用 zssh,但有一次我必须连接到一个只能接受一个连接的主机,这是必须的。工作正常。