Anthony Labarre
Anthony Labarre

Reputation: 2794

Determining the filesystem type from a path in Python

Is there any portable way in Python (2.*) to obtain the filesystem type of the device containing a given path? For instance, something like:

>>> get_fs_type("/foo/bar")
'vfat'

Upvotes: 6

Views: 7687

Answers (5)

am70
am70

Reputation: 729

for linux, installing the stat command, I used

P = subprocess.run(['stat', '-f', '-c', '%T', path],
                    capture_output=True, text=True)
fstype = P.stdout.strip().lower()

Edit: adding text=True will return the result as a str otherwise it will be bytes. Also you may want to check that P.returncode == 0. Moreover, you may want to use functools.cache to cache results, if this code is called frequently

Upvotes: 1

bgav
bgav

Reputation: 1

For anyone prioritizing concision here's a slightly shorter version of gena2x's answer:

def get_fs_type(path):
    path_matching_fstypes_mountpoints = [
        part for part in disk_partitions() 
        if str(path.resolve()).startswith(part.mountpoint)
    ]
    return sorted(path_matching_fstypes_mountpoints, key=lambda x: len(x.mountpoint))[-1].fstype

Upvotes: -1

gena2x
gena2x

Reputation: 364

import psutil

def get_fs_type(path):
    bestMatch = ""
    fsType = ""
    for part in psutil.disk_partitions():
        if mypath.startswith(part.mountpoint) and len(bestMatch) < len(part.mountpoint):
            fsType = part.fstype
            bestMatch = part.mountpoint
    return fsType

Upvotes: 1

Rhand
Rhand

Reputation: 897

Here is my solution. I tried to make it more generic for cases where /var/lib is a different partition. Some ugliness crept in the code as windows always has the separator at the end of the mountpoint, while this is omitted in linux. Which means testing them both

import psutil, os
def printparts():
    for part in psutil.disk_partitions():
        print part
def get_fs_type(path):
    partition = {}
    for part in psutil.disk_partitions():
        partition[part.mountpoint] = (part.fstype, part.device)
    if path in partition:
        return partition[path]
    splitpath = path.split(os.sep)  
    for i in xrange(len(splitpath),0,-1):
        path = os.sep.join(splitpath[:i]) + os.sep
        if path in partition:
            return partition[path]
        path = os.sep.join(splitpath[:i])
        if path in partition:
            return partition[path]
    return ("unkown","none")

printparts()

for test in ["/", "/home", "/var", "/var/lib", "C:\\", "C:\\User", "D:\\"]:
    print "%s\t%s" %(test, get_fs_type(test))

On windows:

python test.py
sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed')
sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed')
sdiskpart(device='E:\\', mountpoint='E:\\', fstype='NTFS', opts='rw,fixed')
sdiskpart(device='F:\\', mountpoint='F:\\', fstype='', opts='cdrom')
sdiskpart(device='G:\\', mountpoint='G:\\', fstype='', opts='cdrom')
/       ('unkown', 'none')
/home   ('unkown', 'none')
/var    ('unkown', 'none')
/var/lib        ('unkown', 'none')
C:\     ('NTFS', 'C:\\')
C:\User ('NTFS', 'C:\\')
D:\     ('NTFS', 'D:\\')

On linux:

python test.py
partition(device='/dev/cciss/c0d0p1', mountpoint='/', fstype='ext4', opts='rw,errors=remount-ro')
partition(device='/dev/cciss/c0d1p3', mountpoint='/home', fstype='ext4', opts='rw')
partition(device='/dev/cciss/c0d1p2', mountpoint='/var', fstype='ext4', opts='rw')
/       ('ext4', '/dev/cciss/c0d0p1')
/home   ('ext4', '/dev/cciss/c0d1p3')
/var    ('ext4', '/dev/cciss/c0d1p2')
/var/lib        ('ext4', '/dev/cciss/c0d1p2')
C:\     ('unkown', 'none')
C:\User ('unkown', 'none')
D:\     ('unkown', 'none')

Upvotes: 4

Anthony Labarre
Anthony Labarre

Reputation: 2794

Thanks to user3012759's comment, here's a solution (certainly improvable upon but nonetheless working):

import psutil

def get_fs_type(mypath):
    root_type = ""
    for part in psutil.disk_partitions():
        if part.mountpoint == '/':
            root_type = part.fstype
            continue

        if mypath.startswith(part.mountpoint):
            return part.fstype

    return root_type

A separate treatment was needed for "/" under GNU/Linux, since all (absolute) paths start with that.

Here's an example of the code "in action" (GNU/Linux):

>>> get_fs_type("/tmp")
'ext4'
>>> get_fs_type("/media/WALKMAN")
'vfat'

And another one under Windows (XP if it matters):

>>> get_fs_type("C:\\")  # careful: "C:" will yield ''
'NTFS'

Upvotes: 3

Related Questions