前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tar解压进度查看

tar解压进度查看

原创
作者头像
大大刺猬
发布2024-03-04 15:11:45
2950
发布2024-03-04 15:11:45

导读

之前有写mysql数据导入进度查看, 现在又想看下其它比较耗时的进度了, 比如查看tar解压的剩余时间, 虽然解压通常很快(顺序IO), 但有个时间, 尤其是进度条 会显得很高大上 -_-

其实主要是顺便改进下脚本, 支持多个进程的进度查看.

原理

还是和之前一样的, 查看当前的 /proc/PID/iorchar 然后除以总大小, 就得到进度了. 剩余大小再除以速度就是剩余时间了.

又区别的就是, 我们可以使用如下命令查看 压缩包解压后的大小.

gzip

代码语言:shell
复制
gzip -l /root/mysql-5.7.43-linux-glibc2.12-x86_64.tar.gz

xz

代码语言:shell
复制
xz -l /root/mysql-8.0.33-linux-glibc2.12-x86_64.tar.xz

由于我们要支持多个进度条同时显示, 我们就要固定进度条的位置(行号). 可以使用 ANSI escape code来定位光标,并打印进度条. 还是来看时间演示例子吧.

测试

这里同时解压 xz 和 gz 文件 , 方便观察

代码语言:bash
复制
tar -xvf mysql-5.7.43-linux-glibc2.12-x86_64.tar.gz
tar -xvf mysql-8.0.33-linux-glibc2.12-x86_64.tar.xz

然后使用本脚本(见文末)来观察进度

代码语言:bash
复制
sh tar_gz_or_xz_progress_view.sh

我们可以看到 gzip 压缩率比 xz高, 解压速度还更快. 建议使用gzip来压缩

我们就可以动态的看到解压进度了. 那么这有啥用呢? 没啥用, 光是花里胡哨的. 不, 这可以让我们的终端看起来更酷. 写脚本的时候, 就可以把这个脚本带上, 让我们的其它脚本也花里胡哨的更优雅.

附源码

github地址: https://github.com/ddcw/ddcw/blob/master/shells/tar_gz_or_xz_progress_view.sh

tar_gz_or_xz_progress_view.sh 也可以见如下:

直接使用, 不需要参数. SLEEP_INTERNAL 表示每隔多少秒显示一次. 就是显示频率

代码语言:bash
复制
#!/usr/bin/env bash
#write by ddcw @https://github.com/ddcw
# tar.gz/tar.xz 解压进度查看脚本

export LANG="en_US.UTF-8"
SLEEP_INTERNAL=0.1

jindutiao2(){
	PID=$1
	lineno=$2
	PRONAME=`cat /proc/${PID}/comm`
	FILENAME=`ls -l /proc/${PID}/fd/0 | awk '{print $NF}'`
	SOURCE_SIZE=`stat -c "%s" ${FILENAME} | awk '{size = $1; if (size < 1024) { printf "%.2f B\n", size } else if (size < 1024 * 1024) { printf "%.2f KiB\n", size / 1024 } else if (size < 1024 * 1024 * 1024) { printf "%.2f MiB\n", size / 1024 / 1024 } else { printf "%.2f GiB\n", size / 1024 / 1024 / 1024 } }'`
	if [ "${PRONAME}" == "xz" ];then
		DEST_SIZE="`xz -l ${FILENAME} | tail -1 | awk '{print $5,$6}'`"
	elif [ "${PRONAME}" == "gzip" ];then
		DEST_SIZE="`gzip -l ${FILENAME} | tail -1 | awk '{print $2}' | awk '{size = $1; if (size < 1024) { printf "%.2f B\n", size } else if (size < 1024 * 1024) { printf "%.2f KiB\n", size / 1024 } else if (size < 1024 * 1024 * 1024) { printf "%.2f MiB\n", size / 1024 / 1024 } else { printf "%.2f GiB\n", size / 1024 / 1024 / 1024 } }'`"
	else
		break
	fi
	TOTAL_SIZE=`stat -c '%s' ${FILENAME}`
	CURRENT_SIZE=0
	OLD_SIZE=`awk '{ if ($1=="rchar:") print $2}' /proc/${PID}/io 2>/dev/null`
	START_TIME=`date +%s`
	CURRENT_RATE="0 B/s"
	#不使用 kill -0 pid , 怕审计不过...
	while [ ${CURRENT_SIZE} -lt ${TOTAL_SIZE} ] && [ -d /proc/${PID} ];do
		CURRENT_SIZE=`awk '{ if ($1=="rchar:") print $2}' /proc/${PID}/io 2>/dev/null`
		TIME_DIFF="$[ $(date +%s) - ${START_TIME}  ]"
		if [ "${CURRENT_SIZE}" == "" ];then
			break
		fi
		if [ ${TIME_DIFF} -gt 0 ];then
			CURRENT_RATE=`echo "${OLD_SIZE} ${CURRENT_SIZE} ${TIME_DIFF}" | awk '{print ($2-$1)/$3}' | awk '{size = $1; if (size < 1024) { printf "%.2f B/s\n", size } else if (size < 1024 * 1024) { printf "%.2f KiB/s\n", size / 1024 } else if (size < 1024 * 1024 * 1024) { printf "%.2f MiB/s\n", size / 1024 / 1024 } else { printf "%.2f GiB/s\n", size / 1024 / 1024 / 1024 } }'`
			REST_TIME=`echo "${TOTAL_SIZE} ${CURRENT_SIZE} ${TIME_DIFF} ${OLD_SIZE}" | awk '{print ($1-$2)/(($2-$4)/$3)}' | awk '{printf "%.2f seconds\n",$1}'`
		else
			CURRENT_RATE="0 B/s"
			REST_TIME="0"
		fi
		filled_len=$((CURRENT_SIZE * 50 / ${TOTAL_SIZE}))
		bar=$(printf "%-${filled_len}s" "#" | sed 's/ /#/g')
		spaces=$(printf "%-$((50-filled_len))s" "")
		echo -ne "\033[${lineno};0H${PID}: |$bar$spaces| $[ ${CURRENT_SIZE} * 100 / ${TOTAL_SIZE} ]% RATE:${CURRENT_RATE} THE_REST_TIME:${REST_TIME} "
		sleep ${SLEEP_INTERNAL}
	done
	echo -e "\033[${lineno};0H${PID}: Done               ${FILENAME} RATE:${CURRENT_RATE} COMM:${PRONAME}  ${SOURCE_SIZE} --> ${DEST_SIZE}"
}


PIDS=(`pidof gzip`)
PIDS+=(`pidof xz`)
if [ -z ${PIDS}  ];then
	echo "NO gzip or xz is Running. "
	exit 1
fi
current_no=0
clear
for pid in ${PIDS[@]};do
	((current_no++))
	jindutiao2 ${pid} ${current_no} &
done
wait
exit 0

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导读
  • 原理
  • 测试
  • 附源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档