有没有可以解析Linux sysfs的Python模块?

9 投票
3 回答
7327 浏览
提问于 2025-04-16 09:43

大家好,Linux有很多很棒的功能,比如procfssysfs,还有像vmstat这样的工具可以大大扩展这些功能。不过,我需要从这些系统中收集数据,想用一个统一的Python工具,而不是拼凑一堆不同的脚本。

为了做到这一点,我首先需要确认Python是否有我需要的工具,能够有效地解析和处理不同的数据收集点。所以,我的问题的核心是:

有没有现成的Python模块可以处理和解析sysfs对象?

我通过谷歌、新闻组和各种论坛寻找过这样的模块,但还没有找到任何聪明或有效的东西。所以,在我自己动手之前,我想先在这里问问。

3 个回答

1

我不太明白你为什么需要某个特定的东西,实际上它们大多数都是文本文件,你可以直接对它们进行操作。
据我所知,Python没有专门的模块来处理这个。

3

这是来自filmor的回答,不过去掉了int()的转换:

from os import listdir
from os.path import isdir, isfile, islink, join, realpath, normpath
from keyword import iskeyword

_norm = lambda name: name + ('_' if iskeyword(name) else '')

def _denorm(name):
    if name.endswith('_') and iskeyword(name[:-1]):
        return name[:-1]
    else:
        return name

def _norm_path(path):
    return normpath(realpath(path))

class SysFsObject(object):
    __slots__ = ['_path', '__dict__']

    @staticmethod
    def __id_args__(path='/sys'):
        return _norm_path(path)

    def __init__(self, path='/sys'):
        self._path = _norm_path(path)
        if not self._path.startswith('/sys'):
            raise RuntimeError("Using this on non-sysfs files is dangerous!")
        self.__dict__.update(dict.fromkeys(_norm(i) for i in listdir(self._path)))

    def __repr__(self):
        return "<SysFsObject %s>" % self._path

    def __setattr__(self, name, val):
        if name.startswith('_'):
            return object.__setattr__(self, name, val)

        name = _denorm(name)

        p = realpath(join(self._path, name))
        if isfile(p):
            file(p, 'w').write(val)
        else:
            raise RuntimeError

    def __getattribute__(self, name):
        if name.startswith('_'):
            return object.__getattribute__(self, name)

        name = _denorm(name)

        p = realpath(join(self._path, name))
        if isfile(p):
            return open(p, 'r').read()[:-1]
        elif isdir(p):
            return SysFsObject(p)

随便把数据转换成整数是很不靠谱的,甚至可能会带来危险。比如说,如果你在系统文件中使用这段代码,像“0-7”这样的字符串在多处理器系统上总是会被返回。可是有一天,有人把你的代码用在单核系统上,读取同样的系统文件,结果却返回了“0”。

换句话说,任何调用这段代码的函数,如果希望得到系统文件的原始数据类型(字符串),就必须明确地转换成str()。

4

试试这个:

from os import listdir
from os.path import isdir, isfile, islink, join, realpath, normpath
from keyword import iskeyword

_norm = lambda name: name + ('_' if iskeyword(name) else '')

def _denorm(name):
    if name.endswith('_') and iskeyword(name[:-1]):
        return name[:-1]
    else:
        return name

def _norm_path(path):
    return normpath(realpath(path))

class SysFsObject(object):
    __slots__ = ['_path', '__dict__']

    @staticmethod
    def __id_args__(path='/sys'):
        return _norm_path(path)

    def __init__(self, path='/sys'):
        self._path = _norm_path(path)
        if not self._path.startswith('/sys'):
            raise RuntimeError("Using this on non-sysfs files is dangerous!")
        self.__dict__.update(dict.fromkeys(_norm(i) for i in listdir(self._path)))

    def __repr__(self):
        return "<SysFsObject %s>" % self._path

    def __setattr__(self, name, val):
        if name.startswith('_'):
            return object.__setattr__(self, name, val)

        name = _denorm(name)

        p = realpath(join(self._path, name))
        if isfile(p):
            file(p, 'w').write(str(val))
        else:
            raise RuntimeError

    def __getattribute__(self, name):
        if name.startswith('_'):
            return object.__getattribute__(self, name)

        name = _denorm(name)

        p = realpath(join(self._path, name))
        if isfile(p):
            data = open(p, 'r').read()[:-1]
            try:
                return int(data)
            except ValueError:
                return data
        elif isdir(p):
            return SysFsObject(p)

这个代码可能还不够完美,但如果我没记错的话,它是可以工作的 :)

撰写回答