查找包含给定文件的文件系统的大小和可用空间

我在Linux上使用Python 2.6。 什么是最快的方式:

  • 确定哪个分区包含给定的目录或文件?

    例如,假设/dev/sda2挂载在/home ,并且/dev/mapper/foo挂载在/home/foo 。 从string"/home/foo/bar/baz"我想恢复对("/dev/mapper/foo", "home/foo")

  • 然后,获取给定分区的使用情况统计信息? 例如,给定/dev/mapper/foo我想获得分区的大小和可用空间(以字节或大约兆字节为单位)。

    如果您需要与文件关联的设备名称和挂载点,则应调用外部程序来获取此信息。 df将提供您需要的所有信息 – 当被称为df filename它会打印出一个关于包含该文件的分区的行。

    举个例子:

     import subprocess df = subprocess.Popen(["df", "filename"], stdout=subprocess.PIPE) output = df.communicate()[0] device, size, used, available, percent, mountpoint = \ output.split("\n")[1].split() 

    如果你不需要设备名和挂载点,使用os.statvfs()会更好(见其他答案)。

    这不会给出分区的名称,但可以使用statvfs Unix系统调用直接获取文件系统统计信息。 要从Python调用它,请使用os.statvfs('/home/foo/bar/baz')

    结果中的相关领域, 根据POSIX :

     unsigned long f_frsize Fundamental file system block size. fsblkcnt_t f_blocks Total number of blocks on file system in units of f_frsize. fsblkcnt_t f_bfree Total number of free blocks. fsblkcnt_t f_bavail Number of free blocks available to non-privileged process. 

    因此,要理解值,请乘以f_frsize

     import os statvfs = os.statvfs('/home/foo/bar/baz') statvfs.f_frsize * statvfs.f_blocks # Size of filesystem in bytes statvfs.f_frsize * statvfs.f_bfree # Actual number of free bytes statvfs.f_frsize * statvfs.f_bavail # Number of free bytes that ordinary users # are allowed to use (excl. reserved space) 
     import os def get_mount_point(pathname): "Get the mount point of the filesystem containing pathname" pathname= os.path.normcase(os.path.realpath(pathname)) parent_device= path_device= os.stat(pathname).st_dev while parent_device == path_device: mount_point= pathname pathname= os.path.dirname(pathname) if pathname == mount_point: break parent_device= os.stat(pathname).st_dev return mount_point def get_mounted_device(pathname): "Get the device mounted at pathname" # uses "/proc/mounts" pathname= os.path.normcase(pathname) # might be unnecessary here try: with open("/proc/mounts", "r") as ifp: for line in ifp: fields= line.rstrip('\n').split() # note that line above assumes that # no mount points contain whitespace if fields[1] == pathname: return fields[0] except EnvironmentError: pass return None # explicit def get_fs_freespace(pathname): "Get the free space of the filesystem containing pathname" stat= os.statvfs(pathname) # use f_bfree for superuser, or f_bavail if filesystem # has reserved space for superuser return stat.f_bfree*stat.f_bsize 

    我的电脑上的一些示例path名称:

     path 'trash': mp /home /dev/sda4 free 6413754368 path 'smov': mp /mnt/S /dev/sde free 86761562112 path '/usr/local/lib': mp / rootfs free 2184364032 path '/proc/self/cmdline': mp /proc proc free 0 

    PS

    如果在Python≥3.3上,则有shutil.disk_usage(path) ,它返回一个以字节表示的(total, used, free)命名元组。

    这应该使你所问的一切:

     import os from collections import namedtuple disk_ntuple = namedtuple('partition', 'device mountpoint fstype') usage_ntuple = namedtuple('usage', 'total used free percent') def disk_partitions(all=False): """Return all mountd partitions as a nameduple. If all == False return phyisical partitions only. """ phydevs = [] f = open("/proc/filesystems", "r") for line in f: if not line.startswith("nodev"): phydevs.append(line.strip()) retlist = [] f = open('/etc/mtab', "r") for line in f: if not all and line.startswith('none'): continue fields = line.split() device = fields[0] mountpoint = fields[1] fstype = fields[2] if not all and fstype not in phydevs: continue if device == 'none': device = '' ntuple = disk_ntuple(device, mountpoint, fstype) retlist.append(ntuple) return retlist def disk_usage(path): """Return disk usage associated with path.""" st = os.statvfs(path) free = (st.f_bavail * st.f_frsize) total = (st.f_blocks * st.f_frsize) used = (st.f_blocks - st.f_bfree) * st.f_frsize try: percent = ret = (float(used) / total) * 100 except ZeroDivisionError: percent = 0 # NB: the percentage is -5% than what shown by df due to # reserved blocks that we are currently not considering: # http://goo.gl/sWGbH return usage_ntuple(total, used, free, round(percent, 1)) if __name__ == '__main__': for part in disk_partitions(): print part print " %s\n" % str(disk_usage(part.mountpoint)) 

    在我的盒子上面的代码打印:

     giampaolo@ubuntu:~/dev$ python foo.py partition(device='/dev/sda3', mountpoint='/', fstype='ext4') usage(total=21378641920, used=4886749184, free=15405903872, percent=22.9) partition(device='/dev/sda7', mountpoint='/home', fstype='ext4') usage(total=30227386368, used=12137168896, free=16554737664, percent=40.2) partition(device='/dev/sdb1', mountpoint='/media/1CA0-065B', fstype='vfat') usage(total=7952400384, used=32768, free=7952367616, percent=0.0) partition(device='/dev/sr0', mountpoint='/media/WB2PFRE_IT', fstype='iso9660') usage(total=695730176, used=695730176, free=0, percent=100.0) partition(device='/dev/sda6', mountpoint='/media/Dati', fstype='fuseblk') usage(total=914217758720, used=614345637888, free=299872120832, percent=67.2) 

    从Python 3.3开始,使用标准库有一个简单而直接的方法:

     ┌─[james@james-desktop] - [~/temp] - [Fri Sep 30, 01:38] └─[$]> cat free_space.py #!/usr/bin/env python3 import shutil total, used, free = shutil.disk_usage(__file__) print(total, used, free) ┌─[james@james-desktop] - [~/temp] - [Fri Sep 30, 01:38] └─[$]> ./free_space.py 1007870246912 460794834944 495854989312 

    这些数字以字节为单位。 有关更多信息,请参阅文档 。

    对于第一点,你可以尝试使用os.path.realpath来获得一个规范的path,检查/etc/mtab (我实际上build议调用getmntent ,但我找不到一个正常的方式来访问它)find最长的匹配。 (可以肯定的是,你应该stat文件和推测的安装点,以确认它们实际上在同一个设备上)

    对于第二点,使用os.statvfs来获取块大小和使用信息。

    (免责声明:我没有testing过这个,大部分我知道来自coreutils的资料)

    找出它的最简单的方法。

     import os from collections import namedtuple DiskUsage = namedtuple('DiskUsage', 'total used free') def disk_usage(path): """Return disk usage statistics about the given path. Will return the namedtuple with attributes: 'total', 'used' and 'free', which are the amount of total, used and free space, in bytes. """ st = os.statvfs(path) free = st.f_bavail * st.f_frsize total = st.f_blocks * st.f_frsize used = (st.f_blocks - st.f_bfree) * st.f_frsize return DiskUsage(total, used, free) 

    通常/proc目录在Linux中包含这样的信息,它是一个虚拟文件系统。 例如, /proc/mounts提供有关当前安装的磁盘的信息; 你可以直接parsing它。 像topdf这样的工具都使用/proc

    我没有用过,但是如果你想要一个包装,这也可能有帮助: http : //bitbucket.org/chrismiles/psi/wiki/Home

     def disk_stat(): import os hd={} disk = os.statvfs('/usr') percent = (disk.f_blocks - disk.f_bfree) * 100 / (disk.f_blocks -disk.f_bfree + disk.f_bavail) + 1 return percent print disk_stat('/') print disk_stat('/data') 

    你可以使用os的popen()函数。 首先,你应该inputos然后像下面的样例一样使用popen()函数。 另外,你可以分别得到每一部分的命令或者把所有的部分放在一行中。

     #!/usr/bin/env python import os, sys if len(sys.argv) == 1: Partition_Name = "/dev/sda1" elif len(sys.argv) == 2: Partition_Name = sys.argv[1] else: print("Error: Much more parameter!") exit(0) os.system('clear') #Get each element separately: Partition_Size = os.popen('df -h | grep ' + Partition_Name + ' |awk \'{ print $2 }\'').read() Partition_Used = os.popen('df -h | grep ' + Partition_Name + ' |awk \'{ print $3 }\'').read() Partition_Free = os.popen('df -h | grep ' + Partition_Name + ' |awk \'{ print $4 }\'').read() Partition_UsedPercentage = os.popen('df -h | grep ' + Partition_Name + ' |awk \'{ print $5 }\'').read() Partition_MountPoint = os.popen('df -h | grep ' + Partition_Name + ' |awk \'{ print $6 }\'').read() #Get all elements: AllInOne = os.popen('df -h | grep ' + Partition_Name + ' |awk \'{ print "Size: " $2 "\t" "Used: " $3 "\t" "Free: " $4 "\t" "Use%: " $5 "\t" "Mounted on: " $6 }\'').read() print("Partition Name: %s \n" % Partition_Name) print(" Size: \t\t\t%s Used: \t\t\t%s Free: \t\t\t%s Used Percentage: \t%s" %(Partition_Size, Partition_Used, Partition_Free, Partition_UsedPercentage)) print("All in one: \n" + AllInOne) 

    在Linux上testing:

     chmod +x showdfDetailes.py 

    用这个:

     ./showdfDetailes.py /dev/sda1 

    或者使用这个:

     ./showdfDetailes.py 

    输出:

    分区名称:/ dev / sda1

    尺寸:235G

    使用:3.3G

    免费:220G

    使用百分比:2%

    一体:

    尺寸:235G使用:3.3G免费:220G使用%:2%装在:/