25

I'm looking for the number of free bytes on my HD, but have trouble doing so on python.

I've tried the following:

import os

stat = os.statvfs(path)
print stat.f_bsize * stat.f_bavail

But, on OS/X it gives me a 17529020874752 bytes, which is about about 1.6 TB, which would be very nice, but unfortunately not really true.

What's the best way to get to this figure?

pnuts
  • 58,317
  • 11
  • 87
  • 139
Evert
  • 93,428
  • 18
  • 118
  • 189
  • 1
    A cross-platform approach discussed in http://stackoverflow.com/questions/51658/cross-platform-space-remaining-on-volume-using-python/2372171#2372171 – Roman Starkov Apr 25 '10 at 09:54

7 Answers7

39

Try using f_frsize instead of f_bsize.

>>> s = os.statvfs('/')
>>> (s.f_bavail * s.f_frsize) / 1024
23836592L
>>> os.system('df -k /')
Filesystem   1024-blocks     Used Available Capacity  Mounted on
/dev/disk0s2   116884912 92792320  23836592    80%    /
Nicholas Riley
  • 43,532
  • 6
  • 101
  • 124
  • Not sure why, but this only worked for me when I changed the block size (1024) to 512. – MFB Apr 04 '12 at 05:37
  • 1
    What OS/Python version are you using? – Nicholas Riley Apr 04 '12 at 16:23
  • This is deprecated API. https://docs.python.org/2/library/statvfs.html#module-statvfs – JohnTortugo Feb 17 '18 at 01:02
  • 3
    No it isn't. The `statvfs` *module* is deprecated/gone in Python 3.x (it's an old way to expose statvfs output as indices for tuple lookup versus as attributes of an object), but I don't use the module in my answer. However, `os.statvfs` isn't deprecated — in fact it even received updates in 3.6: https://docs.python.org/3.6/library/os.html#os.statvfs. The only change necessary to adapt this for modern Python would be to use integer division (`//`), although `shutil.disk_usage` as in another answer is certainly an easier alternative! – Nicholas Riley Feb 17 '18 at 23:16
  • AttributeError: module 'os' has no attribute 'statvfs' in Python 3.8. – kloddant Jan 03 '23 at 17:03
  • @kloddant That is platform-dependent, which is why (10.5 years ago) I asked about what OS they were using. os.statvfs still exists in Python 3.11, with an availability note. https://docs.python.org/3.11/library/os.html#os.statvfs – Nicholas Riley Jan 12 '23 at 18:22
19

On UNIX:

import os
from collections import namedtuple

_ntuple_diskusage = namedtuple('usage', 'total used free')

def disk_usage(path):
    """Return disk usage statistics about the given path.

    Returned valus is a named tuple 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 _ntuple_diskusage(total, used, free)

Usage:

>>> disk_usage('/')
usage(total=21378641920, used=7650934784, free=12641718272)
>>>

For Windows you might use psutil.

Giampaolo Rodolà
  • 12,488
  • 6
  • 68
  • 60
16

In python 3.3 and above shutil provides you the same feature

>>> import shutil
>>> shutil.disk_usage("/")
usage(total=488008343552, used=202575314944, free=260620050432)
>>> 
ramdaz
  • 1,761
  • 1
  • 20
  • 43
4

Psutil module can also be used.

>>> psutil.disk_usage('/')
usage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)

documentation can be found here.

Serge
  • 1,947
  • 3
  • 26
  • 48
0
def FreeSpace(drive):
    """ Return the FreeSape of a shared drive in bytes"""
    try:
        fso = com.Dispatch("Scripting.FileSystemObject")
        drv = fso.GetDrive(drive)
        return drv.FreeSpace
    except:
        return 0
imp
  • 1,967
  • 2
  • 28
  • 40
-1

It's not OS-independent, but this works on Linux, and probably on OS X as well:

print commands.getoutput('df .').split('\n')[1].split()[3]

How does it work? It gets the output of the 'df .' command, which gives you disk information about the partition of which the current directory is a part, splits it into two lines (just as it is printed to the screen), then takes the second line of that (by appending [1] after the first split()), then splits that line into different whitespace-separated pieces, and, finally, gives you the 4th element in that list.

>>> commands.getoutput('df .')
'Filesystem           1K-blocks      Used Available Use% Mounted on\n/dev/sda3             80416836  61324872  15039168  81% /'

>>> commands.getoutput('df .').split('\n')
['Filesystem           1K-blocks      Used Available Use% Mounted on', '/dev/sda3             80416836  61324908  15039132  81% /']

>>> commands.getoutput('df .').split('\n')[1]
'/dev/sda3             80416836  61324908  15039132  81% /'

>>> commands.getoutput('df .').split('\n')[1].split()
['/dev/sda3', '80416836', '61324912', '15039128', '81%', '/']

>>> commands.getoutput('df .').split('\n')[1].split()[3]
'15039128'

>>> print commands.getoutput('df .').split('\n')[1].split()[3]
15039128
elimisteve
  • 1,771
  • 1
  • 18
  • 22
  • This approach is not terribly reliable as there is no portable method for getting structured output out of `df`. For example, just try mounting an LVM or NFS volume and it will start breaking its output across several lines. – conny May 03 '11 at 12:08
-5

What's wrong with

import subprocess
proc= subprocess.Popen( "df", stdout=subprocess.PIPE )
proc.stdout.read()
proc.wait()
S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 4
    Using straight Python means its OS agnostic. :) – PKKid Apr 24 '09 at 23:38
  • 3
    Its fragile as it relies on an external application to maintain constant formatting as opposed to a system library. – Shane C. Mason Apr 24 '09 at 23:39
  • It's not like the accepted answer is OS-agnostic either... my 2.6 installation on Windows doesn't have an `os.statvfs`. – Roman Starkov Apr 25 '10 at 09:48
  • 2
    @Shane C. Mason: "relies on an external application". The external application is rigidly defined by the POSIX standard. It's as much as part of the OS as the libraries and will always be there. – S.Lott Apr 26 '10 at 11:02
  • What if the path isn't set? Then the user needs to know the full path of the program. That's a deal breaker. – ironMover Mar 02 '15 at 18:23