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 编程不太有经验,所以我很高兴收到对源代码的任何反馈。