【问题标题】:Python script to verify disk space output from Linux用于验证 Linux 磁盘空间输出的 Python 脚本
【发布时间】:2016-01-17 19:35:49
【问题描述】:

我是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 Loop 来存储不同的数组。

在 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 选项的选项,但我不想将值存储在文件中并再次读取它。

【问题讨论】:

标签: python arrays linux 2d


【解决方案1】:

你可以试试这个:

>>> 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% 的所有文件系统

【讨论】:

  • 非常感谢,这是我所期待的输出,还有更多需要学习、贡献和支持的东西
【解决方案2】:

使用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

【讨论】:

    【解决方案3】:

    你可以这样做

    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%'}
    

    【讨论】:

      【解决方案4】:

      作为单行:

      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
      

      【讨论】:

      • Skyler 非常感谢您的帮助 :) 很高兴看到更多人帮助像我们这样的新手
      【解决方案5】:

      新的“子进程”模型包括大量控制以获取外部命令的输出,但代价是:它变得官僚化。

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

      >>> 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 函数,它默认读取来自外部进程的所有输出并将其作为单个字符串返回。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-28
        • 1970-01-01
        • 2016-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-27
        相关资源
        最近更新 更多