我有几个要压缩的大文件。我可以使用例如

tar cvfj big-files.tar.bz2 folder-with-big-files


来完成此操作,问题是我看不到任何进展,所以我不知道需要多长时间或诸如此类的东西。使用v,我至少可以看到每个文件何时完成,但是当文件很少且太大时,这不是最有用。

有没有办法让tar显示更多详细的进度?就像完成百分比或进度条或估计的剩余时间之类的。每个文件或全部或全部。

#1 楼

我更喜欢这样的单行代码:

tar cf - /folder-with-big-files -P | pv -s $(du -sb /folder-with-big-files | awk '{print }') | gzip > big-files.tar.gz


它将有这样的输出:

4.69GB 0:04:50 [16.3MB/s] [==========================>        ] 78% ETA 0:01:21


对于OSX(来自Kenji的答案)

tar cf - /folder-with-big-files -P | pv -s $(($(du -sk /folder-with-big-files | awk '{print }') * 1024)) | gzip > big-files.tar.gz


评论


在OSX上,du不带-b参数,需要回退至:$((du -sk / folder-with | awk'{print $ 1}')* 1024))

–́ıɾuǝʞ
13年11月29日在10:14

不错,一个班轮。你能解释一下吗?还是以某种方式神奇地起作用?

–木崎
2014年10月4日在18:02

可以像上面那样编写命令来提取tar文件吗?

– Krzysztof Szewczyk
2014年11月26日13:47

请注意,直到du命令完成才显示进度,这可能需要一段时间,具体取决于目录的大小,复杂性和碎片。

–Rooster242
19年1月10日在20:11

我参加聚会有点晚,但是我想知道为什么这个答案建议在tar上使用-P选项。鉴于OP并未在压缩包中提到绝对路径的需要,这似乎是个坏建议(并且在提取归档文件时,使用绝对路径可能会引起真正的头痛)。

– Brian A. Henning
19年2月15日在16:25

#2 楼

您可以使用pv实现此目的。要正确报告进度,pv需要知道您要向其扔多少字节。因此,第一步是计算大小(以KB为单位)。您也可以完全删除进度条,只让pv告诉您它已看到多少字节。它会报告“做得那么快”。

% SIZE=`du -sk folder-with-big-files | cut -f 1`


然后:

% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \ 
     bzip2 -c > big-files.tar.bz2


评论


凉。 pv似乎不随Mac OS X一起提供,但是一旦我有一台装有MacPorts的计算机,便可以尝试一下。你能解释一下你在做什么吗?不太清楚第一行到底是做什么的。

–Svish
2010年7月28日在12:10

第一行:获取有关将要处理的字节数的信息。第二行:使用第一行的大小来允许pv渲染“进度”。由于正在传输数据,因此pv不知道还会有多少字节。

– akira
2011年7月22日在10:25

一个加法:SIZE = $((($ SIZE * 1000/1024))-我不知道这在我的特定平台上是否是一个怪癖,因此我没有将其添加到答案中:du返回size,其中1 kb = 1024字节,而pv似乎期望1 kb = 1000字节。 (我在Ubuntu 10.04上)

–伊兹卡塔
2011-12-11在2:27



@lzkata,您总是可以要求du使用您喜欢的块大小,例如du -s --block-size = 1000,或者仅使用纯字节,例如从du和pv通话中删除k。尽管如此,除非另有说明,否则我希望两者都使用1024。例如,--si可以打开du。

– Legolas
2012年2月23日在11:05

或仅删除k-stuff并仅使用纯字节(du -sb和pv -s,不带任何修饰符)。那应该结束所有的混乱。

– akira
2012年2月23日在11:10

#3 楼

更好的进度条..

apt-get install pv dialog

(pv -n file.tgz | tar xzf - -C target_directory ) \
2>&1 | dialog --gauge "Extracting file..." 6 50




评论


这适用于提取,但是您仍然需要执行更复杂的命令之一来创建(这是原始问题)。它仍然可以与那些结合起来;这只是更复杂。

–丹尼尔·H
2014年8月9日下午5:05

#4 楼

在tar信息页面中查看--checkpoint--checkpoint-action选项(就我的发行版而言,手册页中没有包含这些选项的说明→RTFI)。

请参见https://www.gnu .org / software / tar / manual / html_section / tar_26.html

使用这些(也许还有编写自己的checkpoint命令的功能),您可以计算百分比…

评论


这应该是正确的答案。其他人只是解释了一些额外的工具(默认情况下未安装)以实现类似目的。

–胭脂红Giangregorio
16-11-15在14:47

@Sardathrion也许是因为它特定于GNU-tar。

–phk
17-2-24在11:52

#5 楼

受助手回答的启发
另一种方法是使用本机tar选项
FROMSIZE=`du -sk --apparent-size ${FROMPATH} | cut -f 1`;
CHECKPOINT=`echo ${FROMSIZE}/50 | bc`;
echo "Estimated: [==================================================]";
echo -n "Progess:   [";
tar -c --record-size=1K --checkpoint="${CHECKPOINT}" --checkpoint-action="ttyout=>" -f - "${FROMPATH}" | bzip2 > "${TOFILE}";
echo "]"

结果类似于
Estimated: [==================================================]
Progess:   [>>>>>>>>>>>>>>>>>>>>>>>

此处是完整示例

评论


这是一种了不起的方法-感谢您的分享!进度条可能不会经常与估计值完全不匹配,但是它通常只是一个“ off-by-one”错误,并且清楚地指出,这是我会留下来的估计值:)

–乌鸦
20年8月28日在13:53

是的,只是一个估计。但是,请使用du --apparent-size选项,因为它与tar命令的结果更好地匹配。我将使用此选项更新答案(以及引用的链接,看看)

– campisano
20年8月28日在17:35



我实际上是用它来提取压缩档案,所以我用xz --robot --list来获取未压缩的大小并将其输入到您的解决方案中。但是仍然感谢您的更新!

–乌鸦
20年8月29日在6:51

#6 楼

仅使用tar

tar可以选择(自v1.12起)使用--totals=$SIGNO在信号上打印状态信息,例如:

tar --totals=USR1 -czf output.tar input.file
Total bytes written: 6005319680 (5.6GiB, 23MiB/s)


Total bytes written: [...]信息会打印在每个USR1信号上,例如:

pkill -SIGUSR1 tar


来源:


gnu.org-GNU tar-3.7检查tar进度
gnu.org-tar-新闻


评论


要知道原始总大小,我们可以使用du -hs / path。但是,当使用-z标志时,我们如何估计要写入的总字节数?我认为它会小于原始大小

–lucidbrot
19年11月11日在17:07

我问了一个有关我对unix.se的评论的问题

–lucidbrot
19年11月12日在19:27

#7 楼

刚刚注意到了有关MacOS的评论,虽然我认为@akira(和pv)的解决方案更加整洁,但我想我会在我的MacOS盒中使用tar并向其发送SIGINFO信号来追逐预感和快速变通。有趣的是,它有效:)如果您使用的是类似BSD的系统,则应该可以使用,但是在Linux机器上,您可能需要发送SIGUSR1,和/或tar可能无法采用相同的方法。
不利的一面是,它将仅向您提供输出(在stdout上),以显示当前文件的距离,因为我猜测它不知道它正在获取的数据流的大小。 >所以是的,另一种方法是启动tar,并在您想知道它走多远时定期向其发送SIGINFO。
临时手动方法
如果您希望能够临时检查状态,可以在相关窗口中单击control-T(如Brian Swift所述)它将发送SIGINFO信号。我认为,与此有关的一个问题是它将其发送到您的整个链中,因此,如果您这样做:
% tar cvf - folder-with-big-files | bzip2 -c > big-files.tar.bz2

您还将看到bzip2和tar一起报告其状态:
a folder-with-big-files/big-file.imgload 0.79  cmd: bzip2 13325 running 
      14 0.27u 1.02s 

      adding folder-with-big-files/big-file.imgload (17760256 / 32311520)

如果您只想检查您正在运行的tar是否卡住或速度缓慢,则此方法很好用。在这种情况下,您可能不必太担心格式问题,因为这只是快速检查。.
这种自动方法
如果您知道这将需要一段时间,但是想要诸如进度指示器之类的替代方法是,启动您的tar进程,然后在另一个终端中计算出它的PID,然后将其放入脚本中,该脚本只是反复发送信号。例如,如果您具有以下脚本(并用script.sh PID-to-signal interval-to-signal-at调用它):
#!/bin/sh

PID=
INTERVAL=
SIGNAL=29      # excuse the voodoo, bash gets the translation of SIGINFO, 
               # sh won't..

kill -0 $PID   # invoke a quick check to see if the PID is present AND that
               # you can access it..

echo "this process is $$, sending signal $SIGNAL to $PID every $INTERVAL s"
while [ $? -eq 0 ]; do
     sleep $INTERVAL;
     kill -$SIGNAL $PID;    # The kill signalling must be the last statement
                            # or else the $? conditional test won't work
done
echo "PID $PID no longer accessible, tar finished?"

如果以这种方式调用它,由于您仅定位tar,您将获得类似以下的输出
a folder-with-big-files/tinyfile.1
a folder-with-big-files/tinyfile.2
a folder-with-big-files/tinyfile.3
a folder-with-big-files/bigfile.1
adding folder-with-big-files/bigfile.1 (124612 / 94377241)
adding folder-with-big-files/bigfile.1 (723612 / 94377241)
...

我很漂亮。
最后但并非最不重要的一点-我的脚本有点生锈,因此,如果有人想进入并清理/修复/改善代码,请全力以赴:)

评论


如果在命令行上运行tar,则键入control-T将向其发送SIGINFO。如果在脚本中,则可以使用kill -INFO pid来完成

–布莱恩·斯威夫特(Brian Swift)
2012年4月23日4:58在

完全忘记了control-T,显然我已经习惯于为自己的利益散布太多控制台窗口。

– tanantish
2012年4月23日20:21在

为什么在执行kill -l时看不到-SIGINFO

–Felipe Alvarez
13年6月12日在2:32

@FelipeAlvarez因为您可能尚未使用BSD / MAC OS。另请参阅:GNU Linux(Arch Linux)上的SIGINFO丢失

–默默尔
19年11月12日19:17



@tanantish您可以通过使用SIGNAL = $(kill -l SIGINFO)摆脱“ voodoo”(您的措辞不是我的; P),这将具有在没有SIGINFO的系统上失败的优势

–默默尔
19年11月12日19:21

#8 楼

受到Noah Spurrier的回答的启发

 function tar {
  local bf so
  so=${*: -1}
  case $(file "$so" | awk '{print}') in
  XZ) bf=$(xz -lv "$so" |
    perl -MPOSIX -ane '$.==11 && print ceil $F[5]/50688') ;;
  gzip) bf=$(gzip -l "$so" |
    perl -MPOSIX -ane '$.==2 && print ceil $F[1]/50688') ;;
  directory) bf=$(find "$so" -type f | xargs du -B512 --apparent-size |
    perl -MPOSIX -ane '$bk += $F[0]+1; END {print ceil $bk/100}') ;;
  esac
  command tar "$@" --blocking-factor=$bf \
    --checkpoint-action='ttyout=%u%\r' --checkpoint=1
}
 




评论


可能有一点背景和解释?

–木崎
2014年10月4日在18:03

#9 楼

基于tqdm的方法:

tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null


#10 楼

在macOS上,首先请确保您具有所有可用命令,然后使用brew安装缺少的命令(例如pv)。

如果只希望tar不压缩,请执行以下操作:

tar -c folder-with-big-files | pv -s $[$(du -sk folder-with-big-files | awk '{print }') * 1024] > folder-with-big-files.tar


如果要压缩,请选择:

tar cf - folder-with-big-files -P | pv -s $[$(du -sk folder-with-big-files | awk '{print }') * 1024] | gzip > folder-with-big-files.tar.gz



注意:可能需要一段时间在进度条出现之前。首先尝试在较小的文件夹上进行确认,然后再移至带有大文件的文件夹。


#11 楼

您将看不到剩余的数量,但是会看到对命令进行了非常简单的添加后,它仍在进行中。--checkpoint=1000

# tar  xf  file.tar --checkpoint=1000
tar: Read checkpoint 1000
tar: Read checkpoint 2000
tar: Read checkpoint 3000
tar: Read checkpoint 4000
tar: Read checkpoint 5000
tar: Read checkpoint 6000
...


有关https://的更多详细信息/www.gnu.org/software/tar/manual/html_section/tar_25.html

#12 楼

如果您知道文件号而不是全部文件的总大小:

另一种方法(准确性较差但不适合)是使用-l选项,并在Unix管道中发送文件名而不是数据内容。

让我们将12345个文件放到mydir中,命令是:

[myhost@myuser mydir]$ tar cfvz ~/mytarfile.tgz .|pv -s 12345 -l > /dev/null 


您可以事先知道该值(因为您的用例)或使用诸如find + wc之类的命令来发现它:

[myhost@myuser mydir]$ find | wc -l
12345


评论


那么,为什么不将此命令放入子命令呢? =)

–柯比
18年1月9日在14:12

tar cfvz〜/ mytarfile.tgz。 | pv -s $(查找。| wc -l)-l> / dev / null。对你起作用吗?

–柯比
18年1月9日在14:18



#13 楼



使用

安装对话框和pv命令
sudo apt-get install dialog pv


,然后像这样执行tar

(tar cf - /folder-with-big-files | pv -n -s $(du -sb /folder-with-big-files | awk '{print }') | gzip -9 > big-files.tar) 2>&1 | dialog --gauge 'Your backup is in progress...' 7 70


#14 楼

以下是Debian / buster AMD64上的一些普罗米修斯(指标数据)备份:

root# cd /path/to/prometheus/
root# tar -cf - ./metrics | ( pv -p --timer --rate --bytes > prometheus-metrics.tar )


由于没有足够的磁盘空间,已取消了此作业。 />
使用zstd作为tar的压缩器进行实验,并使用pv监视进度:

root# apt-get update
root# apt-get install zstd pv

root# tar -c --zstd -f - ./metrics | ( pv -p --timer --rate --bytes > prometheus-metrics.tar.zst )
10.2GiB 0:11:50 [14.7MiB/s]

root# du -s -h prometheus
62G    prometheus

root# du -s -h prometheus-metrics.tar.zst
11G    prometheus-metrics.tar.zst


#15 楼

在日常使用中,我不需要知道操作的确切百分比进度,只要它正在运行,以及(有时)它接近完成的程度即可。

我最小地解决了这一需求通过显示在自己的行中处理的文件数;在Bash中:

let n=0; tar zcvf files.tgz directory | while read LINE; do printf "\r%d" $((n++)) ; done ; echo


由于我经常使用它,我在.bashrc中定义了一个函数别名:

function pvl { declare -i n=0; while read L ; do printf "\r%d" $((++n)) ; done ; echo ; }


然后简单地:

tar zcvf files.tgz directory | pvl


如果需要,我可以提前计算find directory | wc -l的文件数(或者更好的方法是使用与显示[find directory | pvl]相同的函数来压缩我的文件不耐烦!)。

另一个示例,为虚拟网站设置权限(此后,由于文件名位于文件系统高速缓存中,因此chown -R速度很快):

find /site -print -type d -exec chmod 2750 "{}" \; -o -type f -exec chmod 640 "{}" | pvl


的确,这种横向处理会减慢主操作的速度,但是我认为打印返回字符和几位数字不会太昂贵(此外,等待下一个等号出现或百分位数改变感觉)比主观的数字转换速度慢!)。

#16 楼

如果可以使用7z:

7z a example.tar example/


这将显示扫描驱动器阶段

Scanning the drive:
2608M 139834 Scan  example/file.txt


以及其他一些有用的信息。

Scanning the drive:
157318 folders, 601997 files, 13683142277 bytes (13 GiB)           

Creating archive: example.tar

Items to compress: 759315

    3% 29587 + example/file.txt


#17 楼

对于使用pv进行简单提取。
 pv mysql.tar.gz | tar -x
 

您将获得类似以下的输出:
  249MiB 0:00:19 [14.0MiB/s] [==>                               ] 10% ETA 0:02:44
 

它在起作用:

要在macOS上安装pv,只需使用Homebrew并使用:
 brew install pv
 

在其他系统上,您可以在此处查看源存储库。