Answers:
我更喜欢这样的单人纸:
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 $FILE.tgz | tar xzf - -C $DEST_DIR
tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gz
如果没有此更改,我将会-bash: syntax error near unexpected token ')'
您可以使用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的计算机,就可以尝试一下。你能解释一下你在做什么吗?不太清楚第一行到底是做什么的。
SIZE=$(($SIZE * 1000 / 1024))
-我不知道这在我的特定平台上是否是一个怪癖,因此我没有将其添加到答案中: du
返回大小,其中1 kb = 1024字节,而pv
似乎期望1 kb = 1000个字节。(我在Ubuntu 10.04上)
du
使用您喜欢的块大小,例如du -s --block-size=1000
,或者只使用纯字节,例如k
从du
和pv
调用中删除。不过,1024
除非另有说明,否则我希望两者都可以使用,例如,--si
打开du
。
du -sb
和pv -s
无任何改性剂)。那应该结束所有的混乱。
在tar信息页面中查看--checkpoint
和--checkpoint-action
选项(就我的分布而言,手册页→RTFI中未包含这些选项的描述)。
参见https://www.gnu.org/software/tar/manual/html_section/tar_26.html
有了这些(也许还有编写自己的checkpoint命令的功能),您可以计算百分比…
tar
特定的。
受到助手回答的启发
另一种方法是使用本机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: [>>>>>>>>>>>>>>>>>>>>>>>
一个完整的例子在这里
仅使用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
资源:
刚刚注意到了有关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=$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)
...
我承认,这很漂亮。
最后但并非最不重要的一点-我的脚本有点生锈,因此,如果有人想进入并清理/修复/改进代码,请毕生:)
tar
在命令行上运行,则键入control-T
将向其发送SIGINFO。如果在脚本中执行此操作,则可以使用kill -INFO pid
control-T
,我明明已经习惯了垃圾邮件太多控制台窗口为我自己好..
kill -l
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
}
如果您知道文件号而不是全部文件的总大小:
另一种方法(准确性较差但不适合使用)是使用-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
tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null
。对你起作用吗?
在macOS上,首先确保您具有所有可用的命令,然后pv
使用brew安装缺少的命令(例如)。
如果只想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上的一些普罗米修斯(指标数据)备份:
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