有办法看到每个文件的任何焦油进度吗?
我有几个大文件想压缩。我可以用
tar cvfj big-files.tar.bz2 folder-with-big-files
问题是我看不到任何进度,所以我不知道需要多长时间或类似的东西。使用v
我至少可以看到每个文件完成的时间,但是当文件很少而且很大的时候,这不是最有用的。
有没有办法让 tar 显示更详细的进度?比如说完成的百分比、进度条、预计剩余时间什么的。要么是每个文件,要么是所有文件,要么是两者都有。
我更喜欢这样的单行线。
tar cf - /folder-with-big-files -P | pv -s $(du -sb /folder-with-big-files | awk '{print $1}') | 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 $1}') * 1024)) | gzip > big-files.tar.gz
``` 。
你可以使用 pv 来实现。为了正确地报告进度,pv
需要知道你向它扔了多少字节。所以,第一步是计算大小(以kbyte为单位)。你也可以完全放弃进度条,只让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
然后:
0x1&
查看tar信息页中的--checkpoint
和--checkpoint-action
选项(对于我的发行版,这些选项的描述并不包含在man页面→RTFI)。
参见 https://www.gnu.org/software/tar/manual/html_section/tar_26.html
有了这些(也许还有写你自己的检查点命令的功能),你可以计算一个百分比……
另一种方法是使用原生的tar
选项
FROMSIZE=`du -sk ${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: [>>>>>>>>>>>>>>>>>>>>>>>
一个完整的例子这里。
刚刚注意到关于MacOS的评论,虽然我认为@akira (和pv)的解决方案是much整洁,我想我会追逐一个预感,并在我的MacOS盒子里用tar快速玩耍,并向它发送一个SIGINFO信号。有趣的是,它成功了 :) 如果你是在类似BSD的系统上,这应该可以工作,但是在Linux的盒子上,你可能需要发送一个SIGUSR1,和/或tar
可能不会以同样的方式工作。
缺点是它只会提供一个输出(在stdout上)给你,显示当前文件有多大,因为我猜它不知道它得到的数据流有多大。
所以,是的,另一种方法是启动 tar,并定期向它发送 SIGINFOs,只要你想知道它到了什么程度。怎么做呢?
如果你想能够临时检查状态,你可以在相关的窗口中按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=$1
INTERVAL=$2
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)
...
我承认,这是相当漂亮的。
最后但并非最不重要的 - 我的脚本有点生疏,所以如果有人想去清理/修复/改进代码,请去吧:)
灵感来源于诺亚-斯珀里尔的回答
function tar {
local bf so
so=${*: -1}
case $(file "$so" | awk '{print$2}') 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
}
来源。
在macOS上,首先确保你有所有可用的命令,并使用 brew 安装缺失的命令(例如 pv
)。
如果你只想用tar
不压缩 ,就用:
tar -c folder-with-big-files | pv -s $[$(du -sk folder-with-big-files | awk '{print $1}') * 1024] > folder-with-big-files.tar
如果你想压缩,就用:
tar cf - folder-with-big-files -P | pv -s $[$(du -sk folder-with-big-files | awk '{print $1}') * 1024] | gzip > folder-with-big-files.tar.gz
注意:进度条出现之前可能需要一段时间。先在一个较小的文件夹上尝试,以确保它的工作,然后移动到有大文件的文件夹。
以下是在Debian/buster AMD64上的prometheus(指标数据)备份的一些数字:
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
``` 实验用0x6&作为0x6&的压缩器
在我的日常使用中,我不需要知道操作的确切百分比级别的进度,只需要知道它是否在工作,以及(有时)它接近完成的程度。
我通过在它自己的行中显示处理的文件数量来最小化地解决这个需求;在Bash中:
let n=0; tar zcvf files.tgz directory | while read LINE; do printf "\r%d" $((n++)) ; done ; echo
由于我经常使用这个,我在.Bashrc中定义了一个函数别名。 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
这种横向处理确实会拖慢主操作的速度,但我觉得打印一个回车符和几个数字不能太贵(除此之外,等待下一个等号出现或百分比数字变化的过程,比起主观上炽热的数字变化速度,感觉很慢!)。