du和ls的区别:如何正确计算文件大小
上一篇文章写到的权限检查脚本,后来我又加入了 apk size 对比的功能,分享给组内同事使用后,暴露出一个问题:脚本输出的 apk size 和 Jenkins 出包信息以及电脑上显示的存储大小都有差异。那么,以何为准呢?
以下是同事的提问及我的回复(已过滤敏感信息):
使用脚本发现 APK SIZE 的检测结果,与在 Jenkins 出包信息有差异,且差异不小。
电脑上显示的存储大小也有差异,具体截图如下:
1、使用脚本检查两个版本结果为:
脚本中计算 apk size 的命令是:ls -s -k
ls -- list directory contents
-s Display the number of file system blocks actually used by each
file, in units of 512 bytes, where partial units are rounded up
to the next integer value. If the output is to a terminal, a
total sum for all the file sizes is output on a line before the
listing. The environment variable BLOCKSIZE overrides the unit
size of 512 bytes.
-k If the -s option is specified, print the file size allocation in
kilobytes, not blocks. This option overrides the environment
variable BLOCKSIZE.
如上所示,这个命令的作用是显示每个文件实际占有的文件系统中块(Block)的数量,每个块的大小是 512 字节。
确实,这个命令输出的信息有问题,在新脚本中已更正。具体的解释见第2&3条回复。
2、查看 Jenkins 出包信息,大小差异为 0.25M:
Jenkins 计算 apk size 的命令是:du -k
du -- display disk usage statistics
-k Display block counts in 1024-byte (1-Kbyte) blocks.
du 是 Linux 系统中查看磁盘使用空间的命令,输出的是文件占有系统磁盘空间的块的数量(和上面提到的 ls -s 功能一样),加上参数 -k 可将块的数量转换成 1024 字节(1KB)的形式输出。
本来我最早写 apk size 对比的脚本时也打算用 du -k 的命令,结果发现这个命令在不同系统中会因为块的大小和文件占有磁盘空间大小的不同导致显示的 apk size 大小有差异。
后来转用了 ls -s -k 命令,结果发现,ls -s -k 踏入的是同样的坑(在不同系统中会因为块的大小和文件占有磁盘空间大小的不同导致显示的 apk size 大小有差异)。
说到这里,不得不提一下文件大小的两个概念:
(1)文件占用磁盘空间的大小
(2)文件实际的大小
du -k 和 ls -s -k 属于第一种,计算的都是文件占用磁盘空间的大小。在电脑的文件系统中,存储是以块(Block)为单位的,不同的系统块的大小不一样,比如说 macOS 一个块的大小是 4096 字节。假设一个文件有 4097 字节,4097-4096=1,这个文件在占用了一个块之后,还有一个字节会占用到一个块,而块与块之间是不共享空间的,也就是说,剩下的 1 字节占用了一个块,这个块还空出 4095 字节,但是无法用于存储其他文件。所以,这个大小为 4097 字节的文件占用了 2 个块。而 du -k 和 ls -s -k 计算的正是每个文件占用块的多少。同理可得,其中必定有部分块是没有占满的,所以和实际的文件大小有差异。
那么,如何获得文件实际的大小呢?请看第三条回复
3、查看电脑中存储信息,V122 出现了两个大小的值:
截图中,“通用”条目下的“大小”一行,15538958 字节表示的正是文件实际的大小。而括号中的“磁盘上的 16.4MB”,网上查到有人说是“压缩数据真正需要多少存储空间”(http://www.kbase101.com/question/47039.html),无法判断真假。
文件名右边的“15.5MB”,其实是 15538958bytes/1000/1000=15.538958MB,约等于 15.5MB。
文件的实际大小,可通过 ls -l 获得:
新的脚本已更新为获取文件的实际大小。
脚本如下:
#!/usr/bin/env bash
#清空上次运行后产生的文件
if [[ -f permission_old.txt ]]; then
rm permission_old.txt permission_new.txt
fi
#读取apk文件地址
read -p "请输入上个版本apk文件存放地址:" apk_old
read -p "请输入最新版本apk文件存放地址:" apk_new
#检查apk size
b_size_old=`ls -l ${apk_old} | awk '{print $5}'`
k_size_old=`awk 'BEGIN{printf "%.2f\n", "'${b_size_old}'"/'1024'}'`
m_size_old=`awk 'BEGIN{printf "%.2f\n", "'${k_size_old}'"/'1024'}'`
b_size_new=`ls -l ${apk_new} | awk '{print $5}'`
k_size_new=`awk 'BEGIN{printf "%.2f\n", "'${b_size_new}'"/'1024'}'`
m_size_new=`awk 'BEGIN{printf "%.2f\n", "'${k_size_new}'"/'1024'}'`
#aapt命令解析apk,输出权限到文件
aapt d badging ${apk_old} | grep "uses-permission:" | awk -F "'" '{print $2}' > permission_old.txt
aapt d badging ${apk_new} | grep "uses-permission:" | awk -F "'" '{print $2}' > permission_new.txt
#遍历新版本权限列表,对比旧版本权限列表是否相同,不同则为新增
for x in $(cat permission_new.txt); do
if cat permission_old.txt | grep ${x} > /dev/null; then
echo "hello, world" > /dev/null
else
echo ${x} >> permission_increase.txt
fi
done
#遍历旧版本权限列表,对比新版本权限列表是否相同,不同则为新减少
for y in $(cat permission_old.txt); do
if cat permission_new.txt | grep ${y} > /dev/null; then
echo "hello, world" > /dev/null
else
echo ${y} >> permission_decrease.txt
fi
done
#判断permission_increase.txt是否存在:存在,输出新增权限提醒;不存在,输出无新增权限
if [[ ! -f permission_increase.txt ]]; then
echo "无新增权限"
else
echo "新增权限:"
cat permission_increase.txt
#删除新增权限文件
rm permission_increase.txt
fi
#判断permission_decrease.txt是否存在:存在,输出新减少权限提醒;不存在,输出无新减少权限
if [[ ! -f permission_decrease.txt ]]; then
echo "无新减少权限"
else
echo "新减少权限:"
cat permission_decrease.txt
#删除新减少权限文件
rm permission_decrease.txt
fi
#输出apk size
echo "------"
echo "上个版本apk size: ${m_size_old}MB(${k_size_old}KB)"
echo "最新版本apk size: ${m_size_new}MB(${k_size_new}KB)"
#对比两个版本的apk size大小变化
if [[ `echo "${m_size_new} > ${m_size_old}" | bc` -eq 1 ]]
then
exceeded_size=$(printf "%.2f" `echo "scale=2;${m_size_new}-${m_size_old}"|bc`)
echo "最新版本比上个版本增加${exceeded_size}MB"
else
echo "apk size未增加"
fi
欢迎关注微信公众号"测试开发Stack"
du和ls的区别:如何正确计算文件大小的更多相关文章
- 转 由一次磁盘告警引发的血案:du 和 ls 的区别
如果你完全不明白或者完全明白图片含义, 那么你不用继续往下看了. 否则, 这篇文章也许正是你需要的. 背景 确切地说,不是收到的自动告警短信或者邮件告诉我某机器上的磁盘满了,而是某同学人肉发现该机器写 ...
- linux du与ls查看文件大小时的区别
du和ls查看文件大小的区别 du == disk usage (磁盘使用量,占用的磁盘空间)du 的基本使用du -s #s参数是可以统计占硬盘空间大小的如 du -skh web-k或-- ...
- linux:ls、ls -l、ls -al区别 示例
linux:ls.ls -l.ls -al区别 示例 比如test文件夹下有一个test文件.一个.文件夹.一个..文件夹. 则,执行三个命令后,显示效果如下: [root@linuxserver t ...
- 网络基础、ftp任务(进度条、计算文件大小、断点续传、搭建框架示例)
一.网络基础 1.端口,是什么?为什么要有端口? 端口是为了将同一个电脑上的不同程序进行隔离. IP是找电脑:端口是找电脑上的应用程序: 端口范围:1 – 65535 : 1 - 1024 不要 ...
- php 计算文件大小
计算文件大小 主要计算文件的 size 大小,默认的为Bytes的,所以运用三元运算符,来进行转换. 转换成 Bytes->KB->MB->GB /** * @param $size ...
- 正确计算linux系统内存使用率
参考:https://blog.gesha.net/archives/406/ 图中的例子很典型,就是:多数的linux系统在free命令后会发现free(剩余)的内存很少,而自己又没有开过多的程序或 ...
- linux中du与df的区别和联系
1,两者区别 du,disk usage,是通过搜索文件来计算每个文件的大小然后累加,du能看到的文件只是一些当前存在 的,没有被删除的.他计算的大小就是当前他认为存在的所有文件大小的累加和. df, ...
- AC、HC、AHC、ACT、LS的区别
http://forum.eet-cn.com/thread!printPreview.jspa?threadID=1200029698&start=0 以245为例,74AC245.74HC ...
- ScrollView与ListView合用(正确计算Listview的高度)的问题解决
最近做项目中用到ScrollView和ListView一起使用的问题,显示的时候ListView不能完全正确的显示,查了好多资料终于成功解决: 首先,ListView不能直接用,要自定义一个,然后 ...
随机推荐
- pixijs shader贴图扫光效果
pixijs shader贴图扫光效果 直接贴代码 const app = new PIXI.Application({ transparent: true }); document.body.app ...
- windows下mysql安装和配置
历史版本下载地址安装,解压添加环境变量使用cmd中操作mysql进程修改mysql的配置附录:设置mysql随开机自启 TOC 历史版本下载地址 windows的mysql历史版本,推荐使用5.6版本 ...
- 发布TS类型文件到npm
最近发布了@types/node-observer包到npm,这里记录下发布过程 TS类型文件的包名通常以@types开头,使用npm publish发布以@types开头的包时需要使用付费账号. ...
- Java基础扫盲系列(三)— Java内省技术
前言 Java内省技术属于Java基础体系的的一部分,但是很多人都不甚了解.笔者也是在学习Spring源码的过程中遇到该技术模块的.为了完善技术体系,本文将全面的学习该技术.在提到Java内省技术,就 ...
- LocalDB 从2017更换到2014后一直显示连接不正确解决方案
问题描述:LocalDB 版本混装后出现默认实例创建不成功 无法连接到 (LocalDB)\MSSQLLocalDB. ------------------------------其他信息: 在与 S ...
- [Docker] Win10中安装Docker并运行Nginx镜像
一.安装Docker 进入官网:https://www.docker.com/products/docker-desktop 可能需要先注册登录,很简单的. 点击 Download Desktop f ...
- 【java提高】---patchca生成验证码
Java使用patchca生成验证码 Patchca是Piotr Piastucki写的一个java验证码开源库,打包成jar文件发布,patchca使用简单但功能强大. 本例实现了自定 ...
- 将Windows网络适配器共享网络的ip:192.168.137.1 改为其他IP
修改注册表 方法1 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters 中的: ScopeAddr ...
- Java执行shell脚本并返回结果两种方法的完整代码
Java执行shell脚本并返回结果两种方法的完整代码 简单的是直接传入String字符串,这种不能执行echo 或者需要调用其他进程的命令(比如调用postfix发送邮件命令就不起作用) 执行复杂的 ...
- opencv::KMeans图像分割
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...