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不能直接用,要自定义一个,然后 ...
随机推荐
- git push时出现 Username for 'https://github.com': 仅仅限于github
使用git push origin master是出现如下问题:Username for 'https://github.com': 解决办法: git remote set-url origin g ...
- dubbo入门教程-从零搭建dubbo服务
[原创 转载请注明出处] 本文是学习了dubbo之后自己手动写的,比较通俗,很多都是自己学习之后的理解,写的过程中没有参考任何文章. 另外dubbo也有官方文档,但是比较官方,也可以多看看dubbo的 ...
- Mysql 常用数据类型 占用字节数 [转]
数据类型是定义列中可以存储什么数据以及该数据实际怎么存储的基本规则.Mysql的常用数据类型主要有: 串数据类型:最常用的数据类型,有两种基本的串类型:分别为定长串和不定长串.定长串结束长度固定的字符 ...
- 安装docker后修改docker文件目录
docker会下载容器,运行会挂载磁盘,所以我们需要把docker装在大容量的分区. 安装 https://docs.docker.com/install/linux/docker-ce/centos ...
- Linux 搭建邮件服务器
一.概述: 在配置邮件服务器之前,先解释几个概念. 1.SMTP:简单邮件传输协议 (Simple Mail Transfer Protocol, SMTP) 通常使用Email都很容易,但是Inte ...
- JVM的内存分配策略
1.对象优先在Eden区分配大多数情况下,对象在新生代Eden区中分配.当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC. 2.大对象直接进入老年代 所谓的大对象是指,需要大量连续 ...
- Type Erasure with Pokemon---swift的类型擦除
我感觉这个是swift的设计缺陷. 类型擦除:解决泛型类型作为公用类型的问题 是抽象的公用机制的一种实现方式. 1)类型擦除并不能解决类型不一致的兼容问题,只能解决类似继承一致性的兼容问题. 2)擦除 ...
- Spring整合Mybaits java.sql.SQLException: Access denied for user '***'@'localhost' (using password: YES)
最近在搞Spring和Mybatis的整合,当我们在Spring里面配置数据源,而数据源是从外部的properties文件读取过来的时候就会报错 java.sql.SQLException: Acce ...
- CentOS 6.9安装MySQL 5.6 (使用yum安装)
CentOS 6.9安装MySQL 5.6 (使用yum安装) 移除CentOS默认的mysql-libs [root@test01 srv]# whereis mysqlmysql: /usr/li ...
- JDK1.8新特性——Optional类
JDK1.8新特性——Optional类 摘要:本文主要学习了JDK1.8新增加的Optional类. 部分内容来自以下博客: https://www.cnblogs.com/1ning/p/9140 ...