如何将数据传送至 sftp 连接?

如何将数据传送至 sftp 连接?

ftp 支持put "|..." "remote-file.name"将数据传输到 ftp 连接的命令。sftp 有类似的功能吗?

在 sftp 中我收到以下错误:

sftp 'jmw@backupsrv:/uploads'
sftp> put "| tar -cx /storage" "backup-2012-06-19--17-51.tgz"
stat | tar -cv /storage: No such file or directory

如上所述,sftp 客户端显然不会执行该命令。

我想使用管道命令直接将文件流重定向到 sftp。(因为在将其上传到 sftp 服务器之前没有足够的空间在同一磁盘上创建备份文件。)

答案1

由于这是您通过谷歌搜索该问题找到的第一个结果并且尚未提及,因此我也会在这里添加我找到的解决方案:

您可以使用 curls sftp 实现来实现这一点。由于 curl 可能已安装在许多系统上,因此这可能比使用自定义客户端的解决方案更可取。

使用示例:

pg_dump -d database | pigz -1 | curl -u username -T - sftp://sftpserver/folder/dbbackup.sql.gz

curl使用您的.ssh/known_hosts文件进行密钥验证。如果您的 ssh 客户端使用了 curl 中使用的库不支持的较新的加密标准,则这可能会失败

为了解决这个问题,您可以使用以下命令将其他密钥类型添加到已知主机文件中:

ssh-keyscan sftpserver >> ~/.ssh/known_hosts

或者您可以使用标志禁用密钥验证-k(但我不建议这样做)

答案2

我花了很多时间才找到解决这个问题的方法。它需要两台机器上都有工具 nc (netcat) 和 SSH(不需要 SFTP)。

在这个例子中,我将把需要备份的数据的机器称为 linux-a,将需要接收备份的机器称为 linux-b。

在 linux-a 上,让 netcat 监听一个端口(我取的是 2000)并将其重定向到一个文件。它将一直停留在那里,直到有东西通过该端口。

[kenny@linux-b /var/backups]$ nc -l 2000 > backup.tgz

在 linux-b 上,打开到 linux-a 的 ssh 隧道,我再次使用了端口 2000。这会将您在本地主机的 TCP 端口 2000 上发送的任何内容重定向到 linux-a 的 TCP 端口 2000,netcat 正在监听该端口。

[kenny@linux-a /var/data]$ ssh -L 2000:localhost:2000 -CfN linux-b

现在创建 tar 存档,但将输出发送到 stdout(使用 -)并将其通过管道传输到 gzip 进行压缩。现在将其通过管道传输到另一个 netcat,该 netcat 将其通过 TCP 端口 2000 发送到本地主机。

[kenny@linux-a /var/data]$ tar cf - important-data | gzip -fc | nc localhost 2000

大功告成!在 linux-b 上,netcat 不再监听,并创建了一个新文件。最棒的是,tar 存档从未放在 linux-a 的硬盘上。

[kenny@linux-b /var/backups]$ file backup.tgz 
backup.tgz: gzip compressed data, from Unix, last modified: Thu Jul  5 13:48:03 2012

我知道这并不是你在问题中要求的,但如果你有 netcat 可用,它就是解决你这类问题的可行方法。

编辑:我忘了一件事:如果你按照这些说明操作,你仍然会在 linux-a 上有一个 SSH 隧道。找出进程 ID 并将其终止。

[kenny@linux-a /var/data]$ ps -ef | grep "ssh -L"
kenny     5741     1  0 13:40 ?        00:00:00 ssh -L 2000:localhost:2000 -CfN linux-b
kenny     5940  3360  0 14:13 pts/1    00:00:00 grep --color=auto ssh -L
[kenny@linux-a /var/data]$ kill 5741

答案3

output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command'如果您的远程用户有一个有效的 shell,则是一个选项。

答案4

voretaq7指出,sftp 客户端不支持仅允许使用 sftp 连接到服务器的用户进行管道数据传输。

幸运的是,有支持 sftp 的 libssh2。所以我们只需要另外 2 个使用 libssh2 的客户端,我称之为:

  • sftp_stdin_upload(上传到 sftp 服务器)
  • sftp_stdout_download(从 sftp 服务器下载)

源代码可以在以下网址找到: http://www.qxs.ch/2012/07/05/sftp-upload-tool/


由于我对 libssh2 编程不太有经验,所以我很高兴收到对源代码的任何反馈。

相关内容