Reputation: 2794
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
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
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
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
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
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