【问题标题】:Upload output of a program directly to a remote file by ftp通过 ftp 将程序的输出直接上传到远程文件
【发布时间】:2023-12-28 04:04:01
【问题描述】:

我有一些程序会生成大量数据,特别是加密压缩包。我想在远程 ftp 服务器上上传结果。

文件很大(大约 60GB),所以我不想为 tmp 目录和时间浪费硬盘空间。

有可能吗?我检查了 ncftput util,但没有从标准输入读取的选项。

【问题讨论】:

  • 我的错,很多 c++ 编码:)

标签: linux bash ftp


【解决方案1】:

curl 可以一边从标准输入读取一边上传:

-T, --upload-file

[...]

使用文件名“-”(单破折号)来使用标准输入而不是给定的 文件。或者,文件名“。” (一个时期)可能是 指定而不是“-”以在非阻塞模式下使用标准输入以允许 在上传标准输入时读取服务器输出。

[...]

【讨论】:

  • cat oldname.txt | curl -T - ftp.example.com/newname.txt --user myuser。就我而言,这会提示我输入密码,并将文件上传为newname.txt
【解决方案2】:

我猜你可以使用任何使用命名管道的上传程序来做到这一点,但我预见到如果上传的某些部分出错并且你必须重新上传:数据已经消失了,你即使您只丢失了 1 个字节,也无法重新开始上传。这也适用于 从标准输入读取 策略。

我的策略如下:

  1. 使用mkfifo 创建命名管道。
  2. 在后台启动写入该命名管道的加密过程。很快,管道缓冲区将满,加密过程将被阻止尝试将数据写入管道。当我们稍后从管道中读取数据时,它应该会解除阻塞。
  3. 从命名管道中读取一定数量的数据(比如说 1 GB)并将其放入文件中。实用程序 dd 可用于此目的。
  4. 通过 ftp 以标准方式上传该文件。然后,您可以处理重试和网络错误。上传完成后,删除文件。
  5. 返回第 3 步,直到从管道中获得 EOF。这意味着加密过程已完成写入管道。
  6. 在服务器上,按顺序将文件追加到一个空文件中,一旦追加,文件就会一个一个地删除。使用touch next_file; for f in ordered_list_of_files; do cat $f >> next_file; rm $f; done 或一些变体应该可以做到。

您当然可以在上传前一个文件的同时准备下一个文件,以最大限度地使用并发性。瓶颈可能是您的加密算法 (CPU)、网络带宽或磁盘带宽。

此方法将在客户端浪​​费您 2 GB 的磁盘空间(或更少或更多,具体取决于文件的大小),并在服务器端浪费 1 GB 的磁盘空间。但您可以确定,如果您的上传接近尾声,您将不必再次执行此操作。

如果您想确定传输的结果,您可以在客户端将文件写入磁盘时计算文件的哈希值,并且只有在服务器端验证哈希值后才删除客户端文件.在您使用dd ... | tee local_file | sha1sum 将文件写入磁盘的同时,可以在客户端计算哈希值。在服务器端,您必须在执行 cat 之前计算哈希,如果哈希不好,请避免执行 cat,所以如果不读取文件两次(一次用于哈希,一次用于哈希,一次给猫)。

【讨论】:

    【解决方案3】:

    您可以使用 ssh 写入远程文件:

    program | ssh -l userid host 'cd /some/remote/directory && cat - > filename'
    

    【讨论】:

    • 我在远程机器上没有 ssh。
    【解决方案4】:

    这是一个通过 curl 上传到 ftp 站点的示例

    wget -O- http://www.example.com/test.zip | curl -T - ftp://user:password@ftp.example.com:2021/upload/test.zip
    

    【讨论】:

      最近更新 更多