Python 为什么shutils和df报告的磁盘大小有几%的差异?
我正在编写一个简单的监视脚本,希望在其中添加磁盘空间检查。但是,我发现报告的可用空间在系统Python 为什么shutils和df报告的磁盘大小有几%的差异?,python,python-3.x,filesystems,disk,diskspace,Python,Python 3.x,Filesystems,Disk,Diskspace,我正在编写一个简单的监视脚本,希望在其中添加磁盘空间检查。但是,我发现报告的可用空间在系统df和之间是不同的 在安装了三个磁盘的系统上: # df / /mnt/2TB1 /mnt/1TB1 Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 472437724 231418380 216997128 52% / /dev/sdb1 1921802520 1712163440
df
和之间是不同的
在安装了三个磁盘的系统上:
# df / /mnt/2TB1 /mnt/1TB1
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 472437724 231418380 216997128 52% /
/dev/sdb1 1921802520 1712163440 111947020 94% /mnt/2TB1
/dev/sdc1 960380648 347087300 564438888 39% /mnt/1TB1
# python3
Python 3.6.8 (default, Jan 14 2019, 11:02:34)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import shutil
>>> (t, u, f) = shutil.disk_usage('/')
>>> (t, u, f)
(483776229376, 236973805568, 222203674624)
>>> u/t
0.48984177224594366
>>> (t, u, f) = shutil.disk_usage('/mnt/2TB1')
>>> (t, u, f)
(1967925780480, 1753255362560, 114633748480)
>>> u/t
0.8909153891628782
>>> (t, u, f) = shutil.disk_usage('/mnt/1TB1')
>>> (t, u, f)
(983429783552, 355400192000, 578002624512)
>>> u/t
0.361388477290517
差异分别为3%、5%和3%。它从何而来?哪个结果是正确的?曾经1Gb是1024兆字节,但制造商发现了一个营销伎俩,用50兆的名称来调用50000兆字节,于是他们把这些程序搞砸了 因此,不同之处在于这些软件实现如何处理这些Megas,如1000或1024。Python似乎有正确的结果
默认情况下,(
man df
)以1kib块显示数字(大小)。但是,考虑到运算(除以1024)同时应用于除法器和除数(计算百分比时),它会减少自身,因此它不应该与最终结果有任何关系
示例(针对某个目录):
df-b1
(以字节为单位输出)导入系统,shutil
如果len(sys.argv)>1 else/,则path=sys.argv[1]
t、 u,f=shutil.disk\u使用情况(路径)
百分比=100*u/t
打印(“(Python)-卷名\t{:}{:}{:{:}{:.3f}%({:.0f}){:}”。格式(t,u,f,percent,percent,path))
[cfati@cfati-ubtu16x64-0:~]>用于“/”媒体/sf_共享_00”中的f;在“${f}”和python3-c”上执行echo-df“${f}”和&df${f}”和&df${f}和&echo-df-b1${f}Python脚本导入sys,shutil;path=sys.argv[1]如果len(sys.argv)>1 else\“/\”,t,u,f=shutil.disk\u使用率(路径);percent=100*u/t;打印(\“(Python)-卷名\t::}:{.0f:}:{(t,u,f,percent,percent,path))“${f}&&echo&&echo;完成
df/
已使用的文件系统1K块可用使用%已安装在
/dev/mapper/ubtu16x640_lvg0-ubtu16x640_root0 102067544 10999896 85859792 12%/
df-b1/
已使用的文件系统1B块可用的已安装的使用%
/dev/mapper/ubtu16x640_lvg0-ubtu16x640_root0 104517165056 11263893504 8792042708 12%/
上的Python脚本/
(Python)-卷名104517165056 11263893504 8792042708 10.777%(11)/
df/媒体/sf\u共享\u 00
已使用的文件系统1K块可用使用%已安装在
共享\u 00 327679996 155279796 172400200 48%/媒体/sf\u共享\u 00
df-B1/媒体/sf\u共享\u 00
已使用的文件系统1B块可用的已安装的使用%
共享\u 00 335544315904 159006511104 176537804800 48%/media/sf\u共享\u 00
/media/sf_共享_00上的Python脚本
(Python)-卷名335544315904 159006511104 176537804800 47.388%(47)/media/sf_shared_00
如图所示,步骤#2.中的数字(大小)与步骤#3.中的数字(大小)相同。计算百分比(在这三种情况中的任何一种情况下),Python百分比似乎是正确的
我不清楚为什么df会报告这些百分比(没有在源代码中查找),但它可能是(所有的事情都是纯粹的猜测)):
- 它倾向于保护用户(报告的百分比略高于实际值)
- 它与逻辑磁盘单元(扇区)有关。
例如,在4kib(4096)扇区磁盘上,4097字节的文件将占用(通常为4097字节),但考虑到磁盘逻辑单元是扇区(而不是字节-这在某种程度上类似于
),文件将占用2个扇区(8kib),因此其基础规模将大于报告的规模#pragma pack
使用/总计
相同,但df
报告的使用%
字段与100·使用/总计
不同
例如,让我们检查安装在/
上的/dev/sda1
的值
df.total=472437724df.used=231418380
df.available=216997128
df.百分比=52 shutil.total=483776229376
shutil.used=236973805568
shutil.free=222203674624 df.used/df.total=0.4898=shutil.free/shutil.total
但是…
df.used/df.total=0.4898 <强>≠强> 0.52=df.百分比/100 coreutils的df实现对这个问题有一定的启示。它们是相关的。
pct
是百分比
uintmax\u t u100=v->used*100;
uintmax\u t nonroot\u total=v->used+v->available;
pct=u100/非root_总计+(u100%非root_总计!=0);
正如我们所看到的,df
不计算used/total
而是used/(used+free)
。注意used+free
我怀疑…
total
包括为元数据保留的空间,如文件系统中的文件所在位置(根据文件系统的不同,这可能包括fat表、索引节点等)。由于无法将该空间用于常规文件,因此使用使用%
将该空间排除在使用%
中(使用+免费)相反,它不包括元数据
然而,一项测试显示…
这不可能是完整的故事。以下脚本在2 MiB文件中生成FAT12和ext2文件系统。必须使用sudo
执行该脚本
#! /bin/bash
check() {
head -c 2MiB /dev/zero > fs
mkfs."$@" fs
mkdir fsmount
mount -o loop fs fsmount
df fsmount
umount fsmount
rm -r fs fsmount
}
echo fat12:
check fat -F 12
echo ext2:
check ext2
我得到了输出
fat12:
[...]
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 2028 0 2028 0% /tmp/fsmount
ext2:
[...]
Creating filesystem with 2048 1k blocks and 256 inodes
[...]
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 2011 21 1888 2% /tmp/fsmount
请注意,两种情况下,两个总大小都小于2048 KiB=2 MiB的文件系统。两个文件系统都没有任何文件,但对于ext2
df
而言,报告使用了21 KiB(可能与此有关).你能发布u
和t
的值吗?现在我们不知道这些值中哪些不同于df
的值。@Socowi:你说得对——我更新了