仅将文件中的几个字节上传到 SFTP

仅将文件中的几个字节上传到 SFTP

我有一个用例,其中我只需要将文件的一些字节(可以以 GB 为单位)上传到 SFTP 服务器,而不是整个文件。使用 SFTP PUT 命令,将上传整个文件,而不是一些字节。

我不想读取文件,然后将其制作成一个较小的文件,然后将整个较小的文件上传到 SFTP。如果要上传的字节数以 GB 为单位,这可能会占用大量内存。所以,放弃这个选项。

有没有其他方法可以使用 SFTP(可能使用 -o 来使用 ssh 选项)命令来执行此操作。也许像scp:如何仅复制文件的最后 10%?

请提出建议

答案1

标准 OpenSSHsftp客户端不支持部分上传。

如果服务器运行的是常规 Linux,那么您可以直接将数据传送到 SSH 连接,而无需使用 SFTP:

$ tail -c 2G ~/bigfile | ssh myserver "cat > smallchunk"

(这里tail -c 2G只是一个输出文件最后 2 GB 的示例命令。请根据需要进行替换 - 如果您想要前 X 个字节,则需要使用head,如果您想要中间的字节,head|tail则可以使用 或 的某种组合dd。)

可选改进:您可以插入“pv”来显示进度条。

$ tail -c 2G ~/bigfile | pv | ssh myserver "cat > smallchunk"

如果你需要 SFTP,那么lftp可以通过上传命名管道:

  1. 在某处创建一个命名管道:

    $ mkfifo /tmp/pipe
    
  2. 运行一个命令,获取您想要的任何字节,并将它们写入命名管道:

    $ tail -c 2G ~/bigfile > /tmp/pipe &
    

    一旦尝试写入管道,命令将立即暂停。(这与|上例中的无名管道完全相同 - 写入过程将暂停,直到读取过程从管道中读取所有内容,每次 4kB。因此让它&在后台发生。)

  3. 要求 lftp 上传管道:

    $ lftp sftp://myserver
    lftp> put -o smallchunk /tmp/pipe
    2G bytes transferred
    


为了清楚了解管道:这里再次是示例 1...

$ tail -c 2G ~/bigfile | ssh myserver "cat > smallchunk"

...下面是使用示例 2 中的“mkfifo”重写的示例 1:

$ mkfifo /tmp/pipe
$ tail -c 2G ~/bigfile > /tmp/pipe &
$ ssh myserver "cat > smallchunk" < /tmp/pipe

这两种管道的工作方式相同:它们使用管道将一个写入进程连接到一个读取进程。命名管道和无名管道都有一个 4 kB 的缓冲区;每次缓冲区填满时,写入进程就会暂停,直到读取进程获取数据。

相关内容