Python 验证磁盘 space 从 Linux 输出的脚本

Python script to verify disk space output from Linux

我是 python 的初学者,我正在编写一个 python 脚本来验证每个挂载点的利用率是否高于阈值。我能够调用 shell 命令并将输出保存到变量中。但是我无法使用变量拆分字段,检查利用率是否超过阈值并报告错误

/dev/mapper/system-root     20G   18G  1.4G  93% /
udev                       3.9G  248K  3.9G   1% /dev
tmpfs                      3.9G   68K  3.9G   1% /dev/shm
/dev/sda1                  251M   71M  167M  30% /boot
/dev/mapper/system-oracle  128G   43G   79G  36% /opt/app/oracle
/dev/mapper/system-tmp     5.5G  677M  4.5G  13% /tmp
/dev/mapper/system-log     3.0G  140M  2.7G   5% /var/log
/dev/mapper/system-varsog   20G  654M   19G   4% /var/sog
/dev/mapper/system-backup   50G   24G   24G  50% /var/sog/backups

我想将字段 5 和字段 6 存储在一个关联数组中,并使用阈值验证字段 5 并报告它是否高于阈值。

我使用下面的脚本来存储 shell 命令输出,现在我需要通过拆分它的字段来处理,但是我无法将它存储在数组中,因为它是多维的,所以我需要使用For循环存储在不同的数组中。

在 shell awk 和 perl 中很容易做到,但似乎很难 python。

>>> import sys, os, time, threading, subprocess,datetime
>>> diskinfo_raw = subprocess.Popen("df -h", shell=True,stdout=subprocess.PIPE)
>>> output = diskinfo_raw.communicate()[0]
>>> print output

请帮我出主意或参考。我已经使用 loadtxt 选项探索了选项,但我不想将值存储在文件中并再次读取它。

新的 "subprocess" 模型包括很多控制来获取外部命令的输出,但代价是:它变得官僚化。

对于快速脚本,旧方法仍然有效:

>>> import os                                                                                                                                                                     
>>> du = os.popen("df -h").readlines()
>>>      

>>> from pprint import pprint
>>> pprint(du)
['Filesystem      Size  Used Avail Use% Mounted on\n',
 'devtmpfs        7,7G     0  7,7G   0% /dev\n',
 'tmpfs           7,8G  164M  7,6G   3% /dev/shm\n',
 'tmpfs           7,8G  1,2M  7,8G   1% /run\n',
 'tmpfs           7,8G     0  7,8G   0% /sys/fs/cgroup\n',
 '/dev/sda6        24G   12G   12G  51% /\n',
 'tmpfs           7,8G   16K  7,8G   1% /tmp\n',
 '/dev/sda5        24G   19G  4,1G  83% /var\n',
 '/dev/sda3       147G   28G  119G  20% /opt\n',
 '/dev/sda2       391G  313G   79G  81% /home\n',
 'tmpfs           1,6G   20K  1,6G   1% /run/user/1000\n']

新的 subprocess 模块还包括几个快捷方式,无需通过 subprocess.Popen 需要的所有参数即可获得程序的输出:

>>> pprint(subprocess.check_output("df -h".split()).split("\n"))
['Filesystem      Size  Used Avail Use% Mounted on',
 'devtmpfs        7,7G     0  7,7G   0% /dev',
 ...

因此,如您所见,子进程除了 Popen 之外还有 check_output 函数,它默认读取外部进程的所有输出,并且 returns 它作为单个细绳。

您的调用的问题是子流程模型需要外部流程的不同参数作为列表的元素(并且程序名称算作一个参数)。因此,它需要 subprocess.check_output(["df", "-h"]) - 我在上面用 "df -h" 命令行上的 "split" 代替了它,就像我通常在我的代码中所做的那样。

作为 one-liner:

dict((fields[5], fields[4]) for fields in [line.split() for line in output.strip().split("\n")][1:])

扩展解释:

usage = dict()  # Dictionaries are Python's associative arrays
for line in output.strip().split("\n")[1:]: # Get the lines with actual data
    fields = line.split()  # Break the line into fields
    usage[fields[5]] = fields[4]  # Map mount point to usage

使用 df -h 作为数据源:

import re

d = {}
lines = output.split('\n')
next(lines)  # skip headers
for line in lines:
    usage, mount = re.split('\s+', line)[4:]
    d[usage] = mount

你可以这样做

mount_usage = {line.split()[5]: line.split()[4] for line in output.split('\n')}

这将给出一个字典,键是挂载点,值是使用分数。

{'/': '93%', '/dev/shm': '1%', '/dev': '1%', '/boot': '30%', '/tmp': '13%', '/var/sog/backups': '50%', '/opt/app/oracle': '36%', '/var/log': '5%', '/var/sog': '4%'}

你可以试试这个:

>>> import subprocess
>>> threshold = 10
>>> child = subprocess.Popen(['df', '-h'], stdout=subprocess.PIPE)
>>> output = child.communicate()[0].strip().split("\n")
>>> for x in output[1:]:
...     if int(x.split()[-2][:-1]) >= threshold:
...         print x

这将列出磁盘使用率为 10% 或超过 10% 的所有文件系统