Есть ли модуль python для разбора sysfs в Linux? - PullRequest
7 голосов
/ 10 января 2011

Привет всем, в Linux есть много замечательных функций в procfs и sysfs, и такие инструменты, как vmstat, расширяют это совсем немного, но мне нужно собрать данные из множества этих систем в надежде использовать унифицированную утилиту Python вместо того, чтобы собирать кучу разрозненных скриптов.

Чтобы сделать это, мне сначала нужно определить, есть ли в Python биты и кусочки, которые мне нужны для адекватного анализа / обработки различных точек сбора данных. Итак, суть моего вопроса:

Есть ли модуль python, который уже обрабатывает / анализирует sysfs объекты?

Я искал такого зверя через Google, usenet и различные форумы, но пока не нашел ничего умного или функционального. Поэтому, прежде чем я вырежу один, я решил проверить здесь первым.

Ответы [ 3 ]

3 голосов
/ 10 марта 2011

Попробуйте это:

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)

Это не полируется никоим образом, но IIRC это работает:)

3 голосов
/ 12 октября 2013

Из ответа фильма, но с удаленным приведением 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)

Произвольное приведение к int неожиданно и даже опасно.Например, если бы вы использовали этот код в любом из файлов cpulist, распространенных в sysfs, такая строка, как «0-7», всегда возвращалась бы в многопроцессорных системах.Затем, когда-нибудь кто-то использует ваш код в одноядерной системе и читает тот же файл sysfs, который теперь содержит «0», возвращает int.

Другими словами, любая функция, которая вызывает этот код и ожидает получитьсобственный тип данных sysfs (строки) должен явно приводиться к str ().

1 голос
/ 10 января 2011

Не совсем понятно, зачем вам нужно что-то конкретное, по большей части это текстовые файлы, вы можете просто связываться с ними напрямую.
Насколько я знаю, нет никаких модулей Python, которые делают это.

...