繁体   English   中英

发送者和接收者根据请求通过ssh传输文件?

[英]Sender and receiver to transfer files over ssh on request?

我创建了一个程序,它遍历一堆文件并调用其中一些文件:

scp <file> user@host:<remotefile>

但是,在我的情况下,可能需要传输数千个小文件,并且scp正在为每个文件打开一个新的ssh连接,这有很多开销。

我想知道是否没有解决方案,我保持一个进程运行,维护连接,我可以发送它“请求”复制单个文件。

理想情况下,我正在寻找一些发送器和接收器程序的组合,这样我就可以在开始时启动一个进程(1):

ssh user@host receiverprogram

对于每个文件,我调用一个命令(2):

senderprogram <file> <remotefile>

并将(2)的输出传递给(1)的输入,这将导致文件被传输。 最后,我可以发送进程(1)一些信号终止。

优选地,发送器和接收器程序是用于Unix的开源C程序。 他们可以使用套接字而不是管道或任何其他创造性解决方案进行通信。

但是,在迭代它时,每个文件都被传输是一个重要的约束 :收集文件列表然后调用一个scp实例来最后一次传输所有文件是不可接受的。 此外,我只有简单的shell访问接收主机。

更新:我找到了使用ssh的多路复用功能解决连接开销问题的解决方案,请参阅下面的答案。 然而,我正在开始赏金,因为我很想知道是否存在我在这里描述的发送者/接收者程序。 似乎应该存在可以使用的东西,例如xmodem / ymodem / zmodem?

我从另一个角度找到了解决方案。 版本3.9开始 ,OpenSSH支持会话多路复用 :单个连接可以承载多个登录或文件传输会话。 这避免了每个连接的设置成本。

对于问题的情况,我可以首先打开一个连接,在特定位置设置一个带有套接字( -S )的控制主机( -M )。 我不需要会话( -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是您要在正在进入的系统上发送文件的目录
  • /mnt/local_dir是本地安装位置

使用此设置,您只需将文件cplocal_dir ,它就会通过sftp发送到remote_dir remote_host

请注意,只有一个连接,因此几乎没有开销

您可能需要使用标志-o ServerAliveInterval=15来维护无限期连接

您需要在本地安装fuse ,并支持(并配置) sftp的SSH服务器

这种方式可行,而对于其他方面,这种一般方法或多或少是正确的。

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

可能你正在寻找这个: ZSSH

zssh(Zmodem SSH)是一个程序,用于在使用安全shell(ssh)时以交互方式将文件传输到远程计算机。 它旨在成为scp的一种方便的替代方案,允许传输文件而无需打开另一个会话并重新验证自己。

如果可以收集要在单个目录(或目录层次结构)中发送的所有文件,请在ssh上使用rsync。

如果您没有将所有文件放在一个位置,请提供一些有关您想要实现的内容的更多信息,以及为什么您无法将所有文件打包到存档中并将其发送过来。 为什么每个文件立即发送至关重要? 如果文件是在短时间内发送的(比如积累了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

在发送方,我会创建一个命名管道并从管道读取,例如,

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命令。 既然您信任发送代码,那么构造事物可能最容易,因此接收器只需在每一行上调用shell eval ,然后发送类似的东西

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

然后定义本地函数read_and_copy_bytes 获得正确的引用是一个熊,但否则它应该是直截了当的。

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

好像焦油的工作? 将其输出传递给ssh,另一方面将ssh输出传递回tar。

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

新版本的GNOME通过GIO使用GVFS,以便通过不同的后端执行所有类型的I / O. Ubuntu包gvfs-bin提供了各种命令行实用程序,可以让您从命令行操作后端。

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

gvfs-mount sftp:// user @ host /

然后您可以使用gvfs-copy复制文件。 我认为所有文件传输都将通过一个SSH进程执行。 您甚至可以使用ps查看正在使用的进程。

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

一种选择是Conch是使用Twsited框架用Python编写的SSH客户端和服务器实现。 您可以使用它编写一个工具,通过其他协议(HTTP或Unix域套接字,FTP,SSH或其他)接受请求,并通过长时间运行的SSH连接触发文件传输。 事实上,我有几个生产程序使用这种技术来避免多个SSH连接设置。

几周之前, 这里一个非常相似的问题 接受的答案建议在ssh到远程机器时打开隧道并使用该隧道进行scp传输。

Perhapse 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. tar文件
  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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM