Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么shutils和df报告的磁盘大小有几%的差异?_Python_Python 3.x_Filesystems_Disk_Diskspace - Fatal编程技术网

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(默认情况下,以KiB输出)
  • 运行
    df-b1
    (以字节为单位输出)
  • 运行以下Python脚本:

    导入系统,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字节),但考虑到磁盘逻辑单元是扇区(而不是字节-这在某种程度上类似于
      #pragma pack
      ),文件将占用2个扇区(8kib),因此其基础规模将大于报告的规模
    如前所述,两种工具的比率
    使用/总计
    相同,但
    df
    报告的
    使用%
    字段与
    100·使用/总计
    不同

    例如,让我们检查安装在
    /
    上的
    /dev/sda1
    的值

    df.total=472437724
    df.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:你说得对——我更新了