0

I need to write a code that will loop through the output of command "df -h" and check if it's 100% utilized and print that specific line in red and if it's 80% utilized, the line to be printed in Yellow.

Output should be similar to :

Filesystem      Size  Used Avail Use% Mounted on
***/dev/sda1        44G   44G   44G  100% /***  -> Should be in red.
udev            8.9G  112K  8.9G   1% /dev
tmpfs           8.9G   84K  8.9G   1% /dev/shm
/dev/sdb1       6.9G  4.5G  4.5G  80% /storage/log  -> Should be in yellow.
/dev/sdb2       7.9G  147M  7.4G   2% /storage/ext
/dev/sdc1        25G  173M   24G   1% /storage/artifactory
/dev/sdd1        50G  5.8G   42G  13% /storage/db

The code I have written so far is simple, but I am not quite sure how to loop in the subprocess output and check the used % field.

def DiskSize():
    import subprocess
        dfh = subprocess.Popen(["df","-h"],stdout=subprocess.PIPE)
    for line in iter(dfh.stdout.readline,''):
         print line.rstrip()

Output I get, is the expected :

Filesystem      Size  Used Avail Use% Mounted on
    /dev/sda1        44G   44G   44G  100% /  
    tmpfs           8.9G   84K  8.9G   1% /dev/shm
    /dev/sdb1       6.9G  4.5G  4.5G  80% /storage/log   
    /dev/sdb2       7.9G  147M  7.4G   2% /storage/ext
    /dev/sdc1        25G  173M   24G   1% /storage/artifactory
    /dev/sdd1        50G  5.8G   42G  13% /storage/db

Thanks for your help.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

0

A better way of doing it, would be to do:

import os
try:
    import psutil
except:
    ## Time to monkey patch in all the psutil-functions as if the real psutil existed.
    class disk():
        def __init__(self, size, free, percent):
            self.size = size
            self.free = free
            self.percent = percent

    class psutil():
        def disk_usage(partition):
            disk_stats = os.statvfs(partition)
            free_size = disk_stats.f_bfree * disk_stats.f_bsize
            disk_size = disk_stats.f_blocks * disk_stats.f_bsize
            percent = (100/disk_size)*disk_free
            return disk(disk_size, free_size, percent)

print(psutil.disk_usage('/').percent)

This will use either psutil if present, or use os.statvfs on the partition desired to calculate the free space. Again, this would apply if what you're after - is only the percentage used on a disk/drive/partition.

If you actually need to parse and print the lines, this won't help.
But I'll leave this here as a reference in case it does help anyone passing by trying to parse df -h data :)


Here's a working example if you really do need to go through the trouble:

from select import epoll, EPOLLIN, EPOLLHUP
from subprocess import Popen, STDOUT, PIPE

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

handle = Popen("df -h".split(), stdout=PIPE, stderr=STDOUT)
lines = b''
while handle.poll() is None:
    lines += handle.stdout.read()


for index, line in enumerate(lines.split(b'\n')):
    if index == 0:
        print(line.decode('UTF-8'))
        continue

    parts = line.split(b' ')
    if len(line) > 2:
        percentage = int(parts[-2][:-1]) # as Jean-François said, replace this line with a regexp for better accuracy
        if percentage < 80:
            print(bcolors.WARNING + line.decode('UTF-8') + bcolors.ENDC)
            continue

    print(line.decode('UTF-8'))

This will grab all the data from df -h, iterate over each line, skip the header from being parsed. Fetch the 2:d least item in columns, unless your mounted paths have spaces that is (correct for that if you need to). Remove the % from that column, convert it to a integer and do the check.

Please consider upvoting this answer if you end up using the later of these two. I completely stole the output formatting from him :)

Torxed
  • 22,866
  • 14
  • 82
  • 131