我创建了一个程序,访问一大堆的文件,并援引为一些他们:

scp <file> user@host:<remotefile>

然而,在我的情况下,可能还有成千上万的小文件,需要转移,并scp是打开一个新的ssh连接用于他们每个人,其中有相当一些开销。

我想知道,如果没有解决方案我在那里保持一个进程的运行,维护连接和我可以把它送"请求"复制过单一文件。

理想的是,我在寻找一个组合的一些方和接收程序,这样,我就可以开始一个进程(1)在开始:

ssh user@host receiverprogram

和对于每个文件,我援引的命令(2):

senderprogram <file> <remotefile>

和管的输出(2)输入(1),这会导致文件被传送。最后,我可以发送过程中(1)有些信号终止。

最好的发送和接收程序都是开放源C节目,用于Unix。他们的通信可以使用一个插座,而不是一个管道,或任何其他创造性的解决方案。

然而,它是一个 重要的制约因素 各文件被转移的时刻,我迭代:这是不可接受的收集清单的文件,然后将调用的一个实例 scp 传送的所有文件在一旦结束。此外,我们仅简单壳的访问接收的主机。

更新: 我发现了一个问题的解决方案的连接的开销用的复功能的ssh,看到我自己的答案如下。然而,我开始一个赏金,因为我是好奇的发现是否存在一个发件人/收程序作为我描述了在这里。它似乎应该有存在的东西可以使用的,例如xmodem/ymodem/zmodem?

有帮助吗?

解决方案

此方式将工作,而对于其他的事情,这一般的方法是或多或少右

(
iterate over file list
  for each matching file
   echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud

其他提示

我发现从另一个角度的溶液。由于版本3.9 时,OpenSSH的支撑件的会话复:一个连接可以携带多个登录或文件传输会话。这避免了每个连接的设立成本。

有关的问题的情况下,我可以先打开带套了一个控制主站(-M)与在特定位置的插座(-S)的连接。我并不需要一个会话(-N)。

ssh user@host -M -S /tmp/%r@%h:%p -N

接着,我可以调用scp对于每个文件,并指示它使用相同的插座:

scp -o 'ControlPath /tmp/%r@%h:%p' <file> user@host:<remotefile>

此命令启动几乎瞬时复制!

您还可以使用用于正常SSH连接控制插座,其然后将立即打开:

ssh user@host -S /tmp/%r@%h:%p

如果该控制插座不再可用(例如,因为你杀主),这回退到正常连接。更多信息可在这篇文章。

有可能会奏效使用SFTP来代替SCP,并把它置于批处理模式。使批处理命令文件作为要执行它们的配管或UNIX域套接字和饲料命令给它。

在此安全可能是在客户端有点棘手。

你有没有尝试过 sshfs?你可以:

sshfs remote_user@remote_host:/remote_dir /mnt/local_dir

在哪里

  • /remote_dir 是您要通过 ssh 连接到的系统上将文件发送到的目录
  • /mnt/local_dir 是本地安装位置

通过此设置,您可以 cp 一个文件到 local_dir 它将被发送过来 sftpremote_host 在其 remote_dir

请注意,只有一个连接,因此开销很小

您可能需要使用该标志 -o ServerAliveInterval=15 维持一个 无限期连接

你需要有 fuse 本地安装和支持(并配置为)的 SSH 服务器 sftp

可能是你正在寻找这样的: ZSSH

  

zssh(ZMODEM SSH)是用于在使用安全外壳(SSH)文件交互传送到远程计算机的程序。它的目的是更方便的替代SCP,允许无需打开另一个会话,并重新验证自己的文件传输。

使用的rsync通过ssh,如果你能收集所有在一个目录发送的文件(或目录的层次)。

如果你没有在一个地方的所有文件,请给一些更多的信息为你想实现什么,为什么你不能所有的文件打包成一个压缩文件并发送过来。为什么如此重要的是每个文件被立即发送?会是OK如果文件具有短延迟(当4K价值的数据已经积累等)发送?

这是一个可爱的小问题。我不知道一个预先包装的解决方案,但你可以做很多事情用简单的shell脚本。我想尝试这种在接收器:

#!/bin/ksh
# this is receiverprogram

while true
do
  typeset -i length
  read filename  # read filename sent by sender below
  read size      # read size of file sent
  read -N $size contents  # read all the bytes of the file
  print -n "$contents" > "$filename"
done

在发送方侧我会创建一个命名管道和从管道,e.g读取。,

mkfifo $HOME/my-connection
ssh remotehost receiver-script < $HOME/my-connection

然后发送一个文件我想尝试这个剧本

#!/bin/ksh
# this is senderprogram

FIFO=$HOME/my-connection

localname="$1"
remotename="$2"
print "$remotename" > $FIFO
size=$(stat -c %s "$localname")
print "$size" > $FIFO
cat "$localname" > $FIFO

如果文件大小大,你可能不希望一气呵成读它,这样的数量级上的东西。

BUFSIZ=8192

rm -f "$filename"
while ((size >= BUFSIZ)); do
  read -N $BUFSIZE buffer
  print -n "$buffer" >> "$filename"
  size=$((size - BUFSIZ))
done
read -N $size buffer
print -n "$contents" >> "$filename"

最终你会想扩展脚本,以便您可以通过chmodchgrp命令。既然你信任发送代码,它可能是最简单的结构的东西,以便接收器只需在每行调用外壳eval,然后把这样的东西

print filename='"'"$remotename"'"' > $FIFO
print "read_and_copy_bytes " '$filename' "$size" > $FIFO

和再定义一个局部函数read_and_copy_bytes。获取引用权利是熊,但除此之外,它应该是简单的。

当然,这一切都不已经过测试!但我希望它给你一些有用的想法。

似乎是焦油工作?管其输出到SSH,而在另一侧配管的ssh输出反馈到焦油。

我认为GNOME桌面访问通过SFTP(SSH)共享时使用单个SSH连接。我猜,这是发生了什么事,因为我看到一个SSH过程,当我访问远程共享这种方式。因此,如果这是真的,你应该能够使用相同的程序用于这一目的。

GNOME的新版本使用的GVFS通过 GIO 以便执行所有通过不同的后端样的I / O。 Ubuntu的包GVFS槽提供的各种命令行实用程序,让你从命令行操纵后端。

首先,您需要安装到您的SSH文件夹:

GVFS贴装SFTP://用户@主机/

然后你可以使用GVFS拷贝到复制文件。我认为所有的文件传输将通过一个单一的SSH过程中进行。甚至可以用ps看到正在使用哪个过程。

如果你觉得更喜欢冒险,你甚至可以在C或提供一个API来GIO其他一些高级语言编写自己的程序。

一个选择是 海螺 是SSH的客户和服务器实现的书面使用Python Twsited 框架。你可以用它来写一个工具,它接受请求通过一些其他议定书》(HTTP或Unix domain sockets,FTP,SSH或任何)和触发文件的传输过一个长期运行的SSH连接。事实上,我有几个方案在生产使用这种技术,以避免多个SSH连接设置。

非常相似的这里的问题的几个星期前。该接受的答案建议开放ssh'ing到远程机器时和使用该隧道传输SCP的隧道。

CurlFTPFS 可能是你一个有效的解决方案。

看起来它只是安装一个外部计算机的文件夹,通过SFTP您的计算机。一旦这样做了,你应该能够使用普通cp命令,一切都将被安全地完成。

不幸的是我没能来测试它自己,但让我知道它是否适合你!

修改1:我已经能够下载并进行测试。正如我担心它不要求客户有一个FTP服务器。 然而后,我发现别的程序不具有完全相同的概念,你在找什么。 sshfs允许您连接到客户端计算机,而无需任何特殊的服务器。一旦你已经安装了一个文件夹,你可以用你的正常cp命令来移动你需要更多的任何文件。一旦你完成,它应该然后是umount /path/to/mounted/folder的笑容问题。让我知道如何工作了!

rsync -avlzp user@remotemachine:/path/to/files /path/to/this/folder

此将使用SSH传输文件,以非缓慢方式

保持简单,编写一个执行类似操作的小包装脚本。

  1. 压缩文件
  2. 发送 tar 文件
  3. 在另一边解压

像这样的东西:

  1. tar -cvzf test.tgz 文件 ....
  2. scp test.tgz user@other.site.com:.
  3. ssh user@other.site.com tar -xzvf test.tgz

/约翰

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top