发送者和接收传送文件的通过ssh在请求?
-
21-08-2019 - |
题
我创建了一个程序,访问一大堆的文件,并援引为一些他们:
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
它将被发送过来 sftp
到 remote_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"
最终你会想扩展脚本,以便您可以通过chmod
和chgrp
命令。既然你信任发送代码,它可能是最简单的结构的东西,以便接收器只需在每行调用外壳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'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传输文件,以非缓慢方式
保持简单,编写一个执行类似操作的小包装脚本。
- 压缩文件
- 发送 tar 文件
- 在另一边解压
像这样的东西:
- tar -cvzf test.tgz 文件 ....
- scp test.tgz user@other.site.com:.
- ssh user@other.site.com tar -xzvf test.tgz
/约翰