当我已经 ssh 进入远程机器时,如何 scp 回到本地?

Posted

技术标签:

【中文标题】当我已经 ssh 进入远程机器时,如何 scp 回到本地?【英文标题】:How to scp back to local when I've already sshed into remote machine? 【发布时间】:2014-10-18 09:05:13 【问题描述】:

我经常遇到这种情况:我 ssh 到远程服务器并运行一些程序,我想将它们的输出文件复制回我的本地计算机。我要做的是记住远程机器上的文件路径,退出连接,然后scp user@remote:filepath .

显然这不是最优的。我正在寻找的是一种让我 scp 文件回到本地机器而不退出连接的方法。我做了一些搜索,几乎所有结果都告诉我如何从我已经知道的本地机器上执行 scp。

这可能吗?更好的是,是否可以不知道我本地机器的 IP 地址?

【问题讨论】:

你为什么不打开另一个终端并从这个终端启动你的scp 命令,而你的ssh 连接仍然在另一个终端中打开?您可以通过 ssh 打开任意数量的与同一台远程计算机的连接。 您可以:echo $(pwd)/*something 获得要复制的文件的完整路径列表。然后用[ctrl]+[z] 挂起ssh 连接,返回到原来的提示,输入scp,然后用fg 恢复ssh 会话,让它重新在前台运行 【参考方案1】:

鉴于您在本地计算机上运行了sshd,这是可能的,您无需知道您的传出 IP 地址。如果启用了 SSH 端口转发,即使您已经打开了 ssh 连接,也可以打开安全隧道,而无需终止它。

假设你有一个到某个服务器的 ssh 连接:

local $ ssh user@example.com
Password:
remote $ echo abc > abc.txt  # now we have a file here

好的,现在我们需要将该文件复制回我们的本地服务器,并且由于某种原因我们不想打开新连接。好的,让我们按Enter ~C(Enter,然后波浪号,然后大写C)来获取ssh命令行:

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

这就像常规的 -L/R/D 选项一样。我们需要-R,所以我们再次点击Enter ~C 并输入:

ssh> -R 127.0.0.1:2222:127.0.0.1:22
Forwarding port.

这里我们将远程服务器的 2222 端口转发到本地机器的 22 端口(这里是您需要在端口 22 上启动本地 SSH 服务器的地方;如果它正在侦听某个其他端口,请使用它而不是 22)。

现在只需在远程服务器上运行 scp 并将我们的文件复制到远程服务器的端口 2222,该端口映射到我们本地计算机的端口 22(我们本地的 sshd 正在运行)。

remote $ scp -P2222 abc.txt user@127.0.0.1:
user@127.0.0.1's password:
abc.txt                   100%    4     0.0KB/s   00:00

我们完成了!

remote $ exit
logout
Connection to example.com closed.
local $ cat abc.txt
abc

棘手,但如果您真的不能从另一个终端运行scp,可能会有所帮助。

【讨论】:

可以在启动 SSH 会话时发出标志-R 127.0.0.1:2222:127.0.0.1:22 吗?所以我可以在我的本地机器上将别名alias ssh="ssh -R 127.0.0.1:2222:127.0.0.1:22" 添加到我的.bashrc,然后在远程机器的.bashrc 中编写一个bash 函数,其内容类似于scp -P2222 $1 user@127.0.0.1:$2?这将使远程机器的 scp'ing 非常有效。 OP 这样做的动机主要是本地机器内的 scp'ing 意味着我不能在文件上使用制表符完成,必须提供整个路径名。 @LukeDavis 是的,您可以将此选项添加到您的 ssh 命令行。我猜OP的问题与在建立连接之前没有进行特殊安排的情况有关。 还有一个问题:222222 是示例对吗?因此,例如,我可以将远程/本地端口号都设为999? @LukeDavis 当然可以。 22 是 sshd 的默认端口,但您的服务可以配置为侦听任何端口。 这太棒了。但是作为一个因为他正在寻找一种简单的方法来做某事而不必打开另一个选项卡并进行新的 scp 连接的人来说,这个解决方案非常有趣。【参考方案2】:

我发现 SU 上的 this one-liner solution 比公认的答案更直接。由于它使用本地IP地址的环境变量,我认为它也满足了OP的要求不提前知道。

基于此,这里有一个“下载”文件的 bash 函数(即从 SSH 会话推送到本地机器上的设定位置)

function dl()
    scp "$1" $CLIENT_IP%% *:/home/<USER>/Downloads

现在我可以在 SSH 连接到远程时调用 dl somefile.txt 并且 somefile.txt 出现在我的本地下载文件夹中。

附加:

我使用 rsa 密钥 (ssh-copy-id) 绕过密码提示 我找到了this trick 以防止在 scp 调用中获取本地 bashrc

注意:这需要从远程通过 SSH 访问本地计算机(任何人都经常这样吗?)

【讨论】:

【参考方案3】:

您需要在您的机器上运行一个本地 ssh 服务器,然后您可以:

    scp [-r] local_content your_local_user@your_local_machine_ip:

无论如何,您不需要关闭远程连接来进行远程复制,只需打开另一个终端并在那里运行 scp。

【讨论】:

【参考方案4】:

其他答案非常好,大多数用户应该能够使用它们。但是,我发现接受的答案有点麻烦,而其他答案不够灵活。介于两者之间的 *** 服务器也给我找出 IP 地址带来了麻烦。

因此,我使用的解决方法是使用我的.bashrc 文件中的以下函数在远程系统上生成所需的scp 命令:

function getCopyCommand 
  echo "scp user@remote:$(pwd)/$1 ."

如果本地系统几乎是远程服务器的镜像(包括用户名)并且我还需要复制目录结构,我发现rsync 更有用。

function getCopyCommand 
  echo "rsync -rvPR user@remote:$(pwd)/$1 /"

然后将生成的 scp 或 rsync 命令简单地粘贴到我的本地终端以检索文件。

【讨论】:

【参考方案5】:

在您的本地计算机上:

scp root@remotemachine_name_or_IP:/complete_path_to_file /local_path

【讨论】:

以上是关于当我已经 ssh 进入远程机器时,如何 scp 回到本地?的主要内容,如果未能解决你的问题,请参考以下文章

scp机器间远程拷贝

Linux SSH远程文件/目录传输命令scp

ssh和alias快速登录远程机器

scp远程传输文件和ssh远程连接

如何使用 SCP 或 SSH 将文件复制到 Python 中的远程服务器?

scp 命令上没有此类文件或目录错误