使用 Python 获取 Linux 系统信息 已翻译 100%

renwofei423 投递于 2013/06/08 10:29 (共 17 段, 翻译完成于 08-01)
阅读 16796
收藏 242
22
加载中

在本文中,我们将会探索使用Python编程语言工具来检索Linux系统各种信息。走你。

哪个Python版本?

当我提及Python,所指的就是CPython 2(准确的是2.7).我会显式提醒那些相同的代码在CPython 3 (3.3)上是不工作的,以及提供一份解释不同之处的备选代码。请确保你已经安装了CPython,在终端上输入python或者python3回车,然后你在终端上应该能看到python的提示符(prompt)。

请注意,所有的程序在它们第一行都是#!/usr/bin/env/python,也就是说,我们想要Python的解释器来执行这些脚本。因此,如果你想你的脚本具有执行性,请使用chmod +x your-script.py, 那么你就可以使用./your-script.py来执行它了(在本文中你将会看到这种方式

LianyouCQ
LianyouCQ
翻译于 2013/07/30 01:44
1

探索platform模块

platform模块在标准库中,它有很多运行我们获得众多系统信息的函数。让我们运行Python解释器来探索它们中的一些函数,那就从platform.uname()函数开始吧:

>>> import platform
>>> platform.uname()
('Linux', 'fedora.echorand', '3.7.4-204.fc18.x86_64', '#1 SMP Wed Jan 23 16:44:29 UTC 2013', 'x86_64')

如果你已知道linux上的uname命令,那么你就会认出来这个函数就是这个命令的一个接口。在Python 2上,它会返回一个包含系统类型(或者内核版本),主机名,版本,发布版本,机器的硬件以及处理器信息元组(tuple)。你可以使用下标访问个别属性,像这样:

>>> platform.uname()[0]
'Linux'

在Python 3上,这个函数返回的是一个命名元组:

>>> platform.uname()

uname_result(system='Linux', node='fedora.echorand',
release='3.7.4-204.fc18.x86_64', version='#1 SMP Wed Jan 23 16:44:29
UTC 2013', machine='x86_64', processor='x86_64')
LianyouCQ
LianyouCQ
翻译于 2013/07/30 01:58
3
因为返回结果是一个命名元组,这就可以简单地通过名字来指定特定的属性,而不是必须记住下标,像这样:
>>> platform.uname().system
'Linux'

platform模块还有一些上面属性的直接接口,像这样:

>>> platform.system()
'Linux'

>>> platform.release()
'3.7.4-204.fc18.x86_64'

linux_distribution()函数返回的有关你所在的linux发布版本的详细信息。例如,在Fedora 18系统上,这个命令会返回如下信息:

>>> platform.linux_distribution()
('Fedora', '18', 'Spherical Cow')

这个返回结果中包含了版本发布名,版本以及代号元组。特定的Python版本支持的发布版本上可以通过_supported_dists显示的值获得。

>>> platform._supported_dists
('SuSE', 'debian', 'fedora', 'redhat', 'centos', 'mandrake',
'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
'UnitedLinux', 'turbolinux')

如果你的linux发布版本不在其中(或者其中之一的衍生发行版)。那么你很可能调用了上面这个函数而看不到任何有用的信息。

LianyouCQ
LianyouCQ
翻译于 2013/07/30 02:19
1

platform模块的最后一个函数,我们将会看看architecture()函数。当你无参的调用这个函数,它会返回包含架构位数以及python可执行的格式的元组,像这样:

>>> platform.architecture()
('64bit', 'ELF')

在32位的系统上,你将会看到:

>>> platform.architecture()
('32bit', 'ELF')

如果你指定了系统上其他任何可执行的,你都将会获得相似的结果,如同这样:

>>> platform.architecture(executable='/usr/bin/ls')
('64bit', 'ELF')

鼓励探索platform模块的除了这些的其它函数,找出你现在运行的Python版本。如果你想知道这个模块是如何获取这些信息的,你可以深入查看PYthon源码目录下的Lib/platform.py文件。

os和sys模块也可以获得一些系统属性,例如原生的字节序。接下来,我们超越Python标准库模块,去探索一些在linux系统通过proc和sysfs文件系统使之访问信息成为可能。注意的是通过文件系统来访问信息将会在不同的硬件架构有所不同。所以在读本文或是写脚本时要时刻记住可以试图从这些文件获取信息。

LianyouCQ
LianyouCQ
翻译于 2013/07/30 02:47
1

CPU信息

/proc/cpuinfo文件包含了你的系统处理器单元的信息。例如,这里就是python版的linux命令cat /proc/cpuinfo所做的事:

#! /usr/bin/env python
""" print out the /proc/cpuinfo
    file
"""

from __future__ import print_function

with open('/proc/cpuinfo') as f:
    for line in f:
        print(line.rstrip('\n'))
当你使用Python 2 或者 Python 3执行这个程序时,你会在屏幕上看到所有/proc/cpuinfo的内容(在上面的程序里,rstrip()方法用来删除每行末尾的换行符)


在下面的代码里列举了使用startwith()字符串方法来显示你的处理器单元的模式。

#! /usr/bin/env python

""" Print the model of your 
    processing units

"""

from __future__ import print_function

with open('/proc/cpuinfo') as f:
    for line in f:
        # Ignore the blank line separating the information between
        # details about two processing units
        if line.strip():
            if line.rstrip('\n').startswith('model name'):
                model_name = line.rstrip('\n').split(':')[1]
                print(model_name)
当你运行这个程序后,你应该会看到你的每个处理器单元的模式名。例如,这里就是在我电脑上所看到的。
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
LianyouCQ
LianyouCQ
翻译于 2013/07/30 03:00
1
迄今为止,我们已有两种方式来找出我们所使用的系统的架构。从技术上讲是正确的,两个方 式实际上报告了你系统运行的内核架构,所以,如果你的电脑是64位的,但是运行的是32位的内核,然后上面的方法还是将会显示为32位的架构。你可以通过从/proc/cpuinfo所列举的标志中查找lm标志,来找到你的电 脑的真实的架构。lm标志代表了长模式,只有64位架构的才会显示它。下面的程序将会指导你怎样做:
#! /usr/bin/env python

""" Find the real bit architecture
"""

from __future__ import print_function

with open('/proc/cpuinfo') as f:
    for line in f:
        # Ignore the blank line separating the information between
        # details about two processing units
        if line.strip():
            if line.rstrip('\n').startswith('flags') \
                    or line.rstrip('\n').startswith('Features'):
                if 'lm' in line.rstrip('\n').split():
                    print('64-bit')
                else:
                    print('32-bit')
LianyouCQ
LianyouCQ
翻译于 2013/07/30 03:10
1
如我们所看到那样,读取/proc/cpuinfo文件以及使用简单文本处理技术就可以获得我们要查找的数据是可能的。为了给其他程序更好的使用这些数据,一个更好的主意就是使/proc/cpuinfo的内容成为标准的数据结构,譬如字典(dictionary)。这个注意很简单:如果你查看这个文件的内容,你就会发现对于每个处理器单元,都有好些键值对(在先前的例子中,我们打印了每个处理器的模型名,即模型名就是关键字)。不同的处理器 单元的信息可以使用空白行隔开。构造一个字典数据结构包含每个处理器单元的关键字是很简单的。对于每个关键字,对于处理器单元的值都在/proc/cpuinfo文件中。下面的代码将会指导你怎么做。
LianyouCQ
LianyouCQ
翻译于 2013/07/30 03:24
1
#!/usr/bin/env/ python

"""
/proc/cpuinfo as a Python dict
"""
from __future__ import print_function
from collections import OrderedDict
import pprint

def cpuinfo():
    ''' Return the information in /proc/cpuinfo
    as a dictionary in the following format:
    cpu_info['proc0']={...}
    cpu_info['proc1']={...}

    '''

    cpuinfo=OrderedDict()
    procinfo=OrderedDict()

    nprocs = 0
    with open('/proc/cpuinfo') as f:
        for line in f:
            if not line.strip():
                # end of one processor
                cpuinfo['proc%s' % nprocs] = procinfo
                nprocs=nprocs+1
                # Reset
                procinfo=OrderedDict()
            else:
                if len(line.split(':')) == 2:
                    procinfo[line.split(':')[0].strip()] = line.split(':')[1].strip()
                else:
                    procinfo[line.split(':')[0].strip()] = ''
            
    return cpuinfo

if __name__=='__main__':
    cpuinfo = cpuinfo()
    for processor in cpuinfo.keys():
        print(cpuinfo[processor]['model name'])
这段代码中使用了OrderedDict(有序字典)而不是常规的字典,能够使用键值有序的存储在文件里。所以,第一个处理器单元的数据之后就是第二个处理器单元的数据,以此类推。你可以使用过滤器来过滤你所查找的信息(如同在if __name__ == '__main__'块中演示的那样)。上面的程序每次执行后都会打印每个处理器单元的模型名(如通过cpuinfo[processor]['model name']语句表明的那样)
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
LianyouCQ
LianyouCQ
翻译于 2013/07/30 03:39
1

内存信息

和/proc/cpuinfo相似,文件/proc/meminfo包含了你电脑的主存的信息。下面的这个程序创建了一个使用这个文件的内容填充的字典。

#!/usr/bin/env python

from __future__ import print_function
from collections import OrderedDict

def meminfo():
    ''' Return the information in /proc/meminfo
    as a dictionary '''
    meminfo=OrderedDict()

    with open('/proc/meminfo') as f:
        for line in f:
            meminfo[line.split(':')[0]] = line.split(':')[1].strip()
    return meminfo

if __name__=='__main__':
    #print(meminfo())
    
    meminfo = meminfo()
    print('Total memory: {0}'.format(meminfo['MemTotal']))
    print('Free memory: {0}'.format(meminfo['MemFree']))
像先前的,通过它的关键字,你可以访问任何你查询的指定信息(在if __name__==__main__块中有所表示)。当你执行这个程序,你该会看到像下面类似的输出:
Total memory: 7897012 kB
Free memory: 249508 kB
LianyouCQ
LianyouCQ
翻译于 2013/07/30 03:46
1

网络统计信息

接下来,我们会探索我们电脑系统的网络设备。我们将会获得系统的网络接口,以及当系统重启之后通过它们数据发送和接受数据的信息。 /proc/net/dev文件让这些信息可用。如果你检查了这个文件的内容,你就会注意到头一两行包含了头信息等等,这个文件第一列是网络接口名,第二和第三列显示了接收和发送的字节数信息(例如总发送字节数,包数,错误等等)。这里我们所感兴趣的就是他哦难过不同的网络设备提取出总发送数据和接收数据。下面的代码展示了怎么从/proc/net/dev文件中提取出这些信息。

#!/usr/bin/env python
from __future__ import print_function
from collections import namedtuple

def netdevs():
    ''' RX and TX bytes for each of the network devices '''

    with open('/proc/net/dev') as f:
        net_dump = f.readlines()
    
    device_data={}
    data = namedtuple('data',['rx','tx'])
    for line in net_dump[2:]:
        line = line.split(':')
        if line[0].strip() != 'lo':
            device_data[line[0].strip()] = data(float(line[1].split()[0])/(1024.0*1024.0), 
                                                float(line[1].split()[8])/(1024.0*1024.0))
    
    return device_data

if __name__=='__main__':
    
    netdevs = netdevs()
    for dev in netdevs.keys():
        print('{0}: {1} MiB {2} MiB'.format(dev, netdevs[dev].rx, netdevs[dev].tx)) 
当你运行上面的程序,下面这个输出就会显示从你最近重启之后网络设备总接收和发送的数据,单位为兆。
em1: 0.0 MiB 0.0 MiB
wlan0: 2651.40951061 MiB 183.173976898 MiB

你可以使用持久的数据存储机制来连接,来写出自己的数据使用监控程序。

LianyouCQ
LianyouCQ
翻译于 2013/07/30 04:03
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(28)

储晓风
储晓风
机器配置不错哦~
DarkAngel
DarkAngel
网络统计信息 部分的Python代码排版有误,最后一行混入了HTML代码
orangleliu
orangleliu
各有各的好
renwofei423
renwofei423

引用来自“samwoo”的评论

英文原文连接提供一下

http://amitsaha.github.io/site/notes/articles/python_linux/article.html
另外你点本篇文章标题下面的英文标题,即原文链接。
s
samwoo
非常棒,谢谢
s
samwoo
英文原文连接提供一下
xiake9527
xiake9527
very cool
LianyouCQ
LianyouCQ

引用来自“水溶C100”的评论

引用来自“JEMYZHANG”的评论

楼上觉得win还能存活多久?

你觉的python还能活多久?

其实不管黑win还是python,都是没有必要的,尽管我都一直使用linux。我们使用它们就是能够给工作或生活带来方面而已。

但是还是喜欢看那些黑得有道理,深入探索之后的黑,也佩服那种人。
水溶C100
水溶C100

引用来自“JEMYZHANG”的评论

楼上觉得win还能存活多久?

你觉的python还能活多久?
PYPlus
PYPlus

引用来自“墨迹”的评论

引用来自“PYPlus”的评论

安装python后,你需要做的事是再安装个ipython

bpython 更爽,层主试试?

试用完毕,用起来很yd,但是缺少一些功能让我毫不犹豫的选择ipython:1、与shell命令的集成(这点非常重要)2、历史命令,bpython有个rewind 3、ipython的magic function很酷。
bpython似乎功能很弱,除了很酷的命令补全提示和语法高亮似乎没什么功能了?

返回顶部
顶部