Найти размер и свободное пространство файловой системы, содержащей данный файл
Я использую Python 2.6 для Linux. Самый быстрый способ:
-
чтобы определить, какой раздел содержит данный каталог или файл?
Например, предположим, что /dev/sda2
установлен на /home
, а /dev/mapper/foo
установлен на /home/foo
. Из строки "/home/foo/bar/baz"
я хотел бы восстановить пару ("/dev/mapper/foo", "home/foo")
.
-
а затем, чтобы получить статистику использования данного раздела? Например, учитывая /dev/mapper/foo
, я хотел бы получить размер раздела и свободного пространства (либо в байтах, либо примерно в мегабайтах).
Ответы
Ответ 1
Если вам просто нужно свободное место на устройстве, см. ответ, используя os.statvfs()
ниже.
Если вам также нужно имя устройства и точка подключения, связанная с файлом, вы должны вызвать внешнюю программу для получения этой информации. 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()
Обратите внимание, что это довольно хрупкое, поскольку оно зависит от точного формата вывода df
, но я не знаю более надежного решения. (Существует несколько решений, основанных на нижеуказанной файловой системе /proc
, которая еще менее переносима, чем эта.)
Ответ 2
Это не дает имя раздела, но вы можете получить статистику файловой системы непосредственно с помощью системного вызова 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)
Ответ 3
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 '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)
, выраженный в байтах.
Ответ 4
Это должно сделать все, что вы просили:
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))
В моем окне приведенный выше код печатает:
[email protected]:~/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)
Ответ 5
Начиная с Python 3.3, есть простой и прямой способ сделать это с помощью стандартной библиотеки:
$ cat free_space.py
#!/usr/bin/env python3
import shutil
total, used, free = shutil.disk_usage(__file__)
print(total, used, free)
$ ./free_space.py
1007870246912 460794834944 495854989312
Эти числа в байтах. Смотрите документацию для получения дополнительной информации.
Ответ 6
Самый простой способ узнать это.
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)
Ответ 7
Для первой точки вы можете попробовать использовать os.path.realpath
, чтобы получить канонический путь, проверьте его на /etc/mtab
(я бы на самом деле предлагать вызов getmntent
, но я не могу найти нормальный способ доступа к нему), чтобы найти самое длинное совпадение. (конечно, вы должны, вероятно, stat
как файл, так и предполагаемую точку монтирования, чтобы убедиться, что они на самом деле находятся на одном устройстве)
Для второго пункта используйте os.statvfs
, чтобы получить размер блока и информацию об использовании.
(Отказ от ответственности: я ничего не тестировал, большинство из того, что я знаю, было получено из источников coreutils)
Ответ 8
import os
def disk_stat(path):
disk = os.statvfs(path)
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')
Ответ 9
Для второй части вашего вопроса: "получить статистику использования данного раздела", psutil упрощает работу с disk_usage (путь). Если задан путь, disk_usage()
возвращает именованный кортеж, включая общее, используемое и свободное пространство, выраженное в байтах, плюс процентное использование.
Простой пример из документации:
>>> import psutil
>>> psutil.disk_usage('/')
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
Psutil работает с версиями Python от 2.6 до 3.6 и Linux, Windows и OSX среди других платформ.
Ответ 10
Обычно каталог /proc
содержит такую информацию в Linux, это виртуальная файловая система. Например, /proc/mounts
предоставляет информацию о текущих установленных дисках; и вы можете разобрать его напрямую. Утилиты, такие как top
, df
, используют /proc
.
Я не использовал его, но это тоже может помочь, если вы хотите оболочку: http://bitbucket.org/chrismiles/psi/wiki/Home
Ответ 11
Вы можете использовать функцию popen() из os. Прежде всего, вы должны импортировать os, а затем использовать функцию 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:
chmod +x showdfDetailes.py
Используйте это:
./showdfDetailes.py /dev/sda1
или используйте это:
./showdfDetailes.py
Вывод:
Название раздела:/dev/sda1
Размер: 235G
Используется: 3.3G
Бесплатно: 220G
Используемый процент: 2%
Все в одном:
Размер: 235G Используется: 3,3G бесплатно: 220G Использование%: 2% Установлено на:/