在 shell 中从远程主机提取大文件时的沙漏/进度

在 shell 中从远程主机提取大文件时的沙漏/进度

我有一个 shell 脚本,用于unzip在 shell 内将一个非常大的文件从远程目录获取到本地目录。这个操作需要相当长的时间,大约20-30分钟。

#!/bin/sh


unzip RemoteHostNFSDirectory -d LocalHostDirectory > output.log

(这是一个 6.2 GB 的文件)。

如何将上述命令嵌入到进度或沙漏栏中,以便用户不会认为它只是挂起并且一旦提取到本地目录成功完成。我可以打印成功或失败的错误。

(我是 shell 新手,如有不便,请谅解。)

答案1

初步说明

显示“进度条或沙漏栏,这样用户就不会认为它只是挂起”,无论是否unzip未挂起都会非常容易。在这个答案中,我假设您不想误导用户。答案试图显示 的进展unzip,而不仅仅是一个虚假的指标。


最直接的方法

如果你的unzip 可以从标准输入读取并且您想要提取整个存档,然后在读取存档时测量进度:

< /path/to/archive.zip pv | unzip -

pv可以被任何显示进度信息并传递数据的工具替代。


其他通用方法

如果您unzip无法从标准输入读取数据,但您确定存档中只有一个文件,并且您知道要用于提取的文件的名称,则提取到标准输出并传递pv以获取进度指示器:

unzip -p /path/to/archive.zip | pv > /extracted/name

如果存档中可能有更多文件,那么您需要指定要提取的单个文件:

unzip -p /path/to/archive.zip internal/path/to/compressed/file | pv > /extracted/name

使用单个文件提取多个文件unzip -p会将它们连接到/extracted/name.要提取多个文件,请运行unzip多次,每次都重定向到不同的路径名。

如果您不知道内部名称,那么您需要事先解析unzip -lunzip -v。通过这种方式,如果您想将其与pv -s.我承认我不知道这些格式总体上有多稳定和可解析(明确)。

有了unzip -p你将不会得到任何日志unzip。依赖其退出状态。如果您需要某种日志,那么 shell 脚本本身应该写入它。脚本必须至少知道/extracted/name,因此它至少可以记录此。


保险丝?

我期待任何基于FUSE的解决方案允许您使用任何能够复制常规文件的工具。进度条可以取决于工具。该命令可能很简单:

pv /mountpoint/internal/path/to/compressed/file > /extracted/name

这不一定对你有帮助。我测试过fuse-zip。看起来它会在实际的复制工具开始工作之前提取(到临时文件或内存中,等等)。所以实际的提取仍然没有任何进度指示;所选工具只能指示稍后复制已提取的文件。缓存“非常大的文件”有其自身的问题,我不确定该工具是否以及如何尝试解决这些问题。无关紧要,因为fuse-zip无论如何都无法解决您原来的问题。

我也测试过archivemount。进度条pv立即开始,但整个设置速度慢得令人痛苦。我发现archivemount即使读取过程按顺序读取,存档内也会来回跳转(查找)。对于您的“非常大的文件”来说,这可能是不切实际的。或许一些调整是可能的,也许我错过了它们。


欺骗pv

一个聪明但有点麻烦的方法是pv -d

unzip /path/to/archive.zip > output.log &
pv -d "$!"
wait "$!"

该方法应该可以让“用户不认为它只是挂起”,尽管在其基本形式中它会向用户展示比您可能想要的更多内容。某些选项pv甚至“手动”解析/proc/$!/fd/proc/$!/fdinfo不解析pv可能会有所帮助。

unzip在后台工作将无法轻松获得用户的响应,因此请考虑unzip -o(谨慎)。

pv终止后会终止,所以如果你想严格等待unzip就不需要。是否可以返回退出状态。waitwait "$!"unzip

相关内容