15

How do I iterate through the mount points of a Linux system using Python? I know I can do it using df command, but is there an in-built Python function to do this?

Also, I'm just writing a Python script to monitor the mount points usage and send email notifications. Would it be better / faster to do this as a normal shell script as compared to a Python script?

Thanks.

3
  • Depends. What do you mean by "monitor"? If you simply want to send an email when something changes, than that will be very easy to do in bash, but if you want something more complicated you'll quickly find that python is the way to go. Commented Sep 30, 2014 at 3:57
  • Sorry, what I meant was to write a cron job which checks for the space occupied in all the mount points and sends email if it reaches a certain threshold. Commented Sep 30, 2014 at 4:09
  • Why not use both? @ventsyv, rightly pointed out, bash would be very easy for file access on the Linux system. Sending email notifications could also be done using bash but however can be done effortlessly in python and you can create simple bash script to combine these scripts. Commented Sep 30, 2014 at 4:27

4 Answers 4

23

The Python and cross-platform way:

pip install psutil  # or add it to your setup.py's install_requires

And then:

import psutil
partitions = psutil.disk_partitions()

for p in partitions:
    print(p.mountpoint, psutil.disk_usage(p.mountpoint).percent)
Sign up to request clarification or add additional context in comments.

3 Comments

psutil is a great package for getting system information that works across all major platforms and deserves to be better known.
notably, things like /proc don't show up in this tool
disk_partitions only shows disk partitions. It misses things like NFS and loop mounts
6

Running the mount command from within Python is not the most efficient way to solve the problem. You can apply Khalid's answer and implement it in pure Python:

with open('/proc/mounts','r') as f:
    mounts = [line.split()[1] for line in f.readlines()]        

import smtplib
import email.mime.text

msg = email.mime.text.MIMEText('\n'.join(mounts))
msg['Subject'] = <subject>
msg['From'] = <sender>
msg['To'] = <recipient>

s = smtplib.SMTP('localhost') # replace 'localhost' will mail exchange host if necessary
s.sendmail(<sender>, <recipient>, msg.as_string())
s.quit()

where <subject>, <sender> and <recipient> should be replaced by appropriate strings.

5 Comments

May not be the most efficient however /proc/mounts doesn't exist on BSD. The OP is using Linux however I personally use mount to target a wider variety of OSes.
True, but the OP mentions Linux specifically.
Yes I updated my comment right away, you caught it before I could save my edit. You are correct. /proc/mount has one deficiency on Linux. If you create a chroot environment and you do mount -o bind within the chroot, /proc/mounts will not list any of the chrooted mounts. However, the mount command (within the chroot) will. df won't either which is why my preferred one is to run mount.
mount -o bind is common place in linux chroots since there are no physical block devices to mount (the paths don't ma directly to a block device). However doing mount -o bind on a Linux system generally doesn't show in /proc/mounts (at least not any Linux kernel/distro I know of yet). However, mount will show you the mounts done with -o bind as well.
@MichaelPetch /proc/mounts does list filesystems mounted with mount -o bind. However, it does so in a confusing manner (the 'device' field in the physical device, not the bound directory, and the filesystem type / mount options do not indicate its a bind mount). Well, at least, on Fedora 20, kernel 3.16.2 it does.
3

I don't know of any library that does it but you could simply launch mount and return all the mount points in a list with something like:

import commands

mount = commands.getoutput('mount -v')
mntlines = mount.split('\n')
mntpoints = map(lambda line: line.split()[2], mntlines)

The code retrieves all the text from the mount -v command, splits the output into a list of lines and then parses each line for the third field which represents the mount point path.

If you wanted to use df then you can do that too but you need to remove the first line which contains the column names:

import commands

mount = commands.getoutput('df')
mntlines = mount.split('\n')[1::] # [1::] trims the first line (column names)
mntpoints = map(lambda line: line.split()[5], mntlines)

Once you have the mount points (mntpoints list) you can use for in to process each one with code like this:

for mount in mntpoints:
    # Process each mount here. For an example we just print each
    print(mount)

Python has a mail processing module called smtplib, and one can find information in the Python docs

2 Comments

Thanks Michael. Is commands.getoutput better than Subprocess.popen if I want to iterate through the result of a shell command?
For something like this I consider getoutput more convenient if you want to redirect stdin and stdout output to a string. Subprocess.popen allows you to do much more with the Pipes. If you need finer control of redirection getoutput isn't much of an option. getoutput specifically returns everything from stdin and stderr and dumps it to a string (in this case a string called mount). Very convenient if all you want is all the output in one large text string. You can use Subprocess.popen to do the same job with more code.
1

The bash way to do it, just for fun:

awk '{print $2}' /proc/mounts | df -h | mail -s `date +%Y-%m-%d` "[email protected]"

1 Comment

open('/proc/mounts').read() is a start for Python. (Awesome answer btw)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.