2011-01-10 8 views
6

हे सब, लिनक्स में procfs और sysfs में बहुत सी शानदार विशेषताएं हैं, और vmstat जैसे टूल काफी विस्तारित हैं, लेकिन मुझे इन प्रणालियों में से कुछ डेटा एकत्र करने की आवश्यकता है और एक एकीकृत पायथन उपयोगिता का लाभ उठाने की उम्मीद कर रहा था अलग-अलग स्क्रिप्ट के एक समूह को एक साथ हैक करने की बजाय।क्या लिनक्स के sysfs को पार्स करने के लिए कोई पायथन मॉड्यूल है?

ऐसा करने के लिए मुझे पहले यह पहचानने की आवश्यकता है कि पाइथन के बिट्स और टुकड़े हैं जिन्हें मुझे अलग-अलग डेटा संग्रह बिंदुओं को पर्याप्त रूप से पार्स/संसाधित करने की आवश्यकता है या नहीं। तो, मेरे प्रश्न का सार:

क्या कोई पाइथन मॉड्यूल है जो पहले से ही sysfs ऑब्जेक्ट्स को हैंडल/पार्स करता है?

मैंने Google, यूजनेट और विभिन्न मंचों के माध्यम से इस तरह के एक जानवर की तलाश की है, लेकिन मुझे अभी तक कुछ बुद्धिमान या कार्यात्मक नहीं मिला है। तो, इससे पहले कि मैंने एक बाहर निकाला, मुझे लगा कि मैं पहले यहां जांच करूंगा।

+0

टक्कर !!! इस प्रश्न के आधार पर [कुछ] (https://github.com/ponycloud/python-sysfs) है –

उत्तर

1

वास्तव में यह सुनिश्चित नहीं है कि आपको कुछ विशिष्ट क्यों चाहिए, वे अधिकांश भाग के लिए सभी टेक्स्ट फाइलें हैं, आप बस उनके साथ सीधे गड़बड़ कर सकते हैं।
कोई पाइथन मॉड्यूल नहीं है जो मुझे पता है।

+2

डुह? इस तरह के मॉड्यूल का बिंदु संरचित तरीके से फ़ाइलों को पढ़ने में समायोजित करना होगा ... यानी sysfs.thermal_zone0.temp –

2

प्रयास करें यह एक:

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 यह काम करता है :) filmor के जवाब से

+0

कोई इसका उपयोग कैसे करता है? क्या यह पता लगाने के लिए निम्न की तरह कुछ है, उदाहरण के लिए, numa नोड?
SysFsObject sysfs प्रिंट sysfs.devices.0000: 80: 00.0.numa_node –

+0

; की तरह आपको लगता है कि सामान के लिए –

+0

(अस्वरूपित अजगर के लिए क्षमा याचना टिप्पणी में एम्बेडेड नई-पंक्तियों की कमी यह असंभव एक टिप्पणी में अजगर कोड लिखने के लिए बनाता है) getattr का उपयोग करना होगा: getattr (sysfs.devices, "0000: 80: 00.0")। numa_node। पायथन न तो अनुमति देता है। और: न ही पहचानकर्ताओं में संख्याओं के साथ शुरू। – filmor

2

, लेकिन पूर्णांक() कास्टिंग हटा दिया साथ:

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 को कास्टिंग अप्रत्याशित और यहां तक ​​कि खतरनाक भी है। उदाहरण के लिए, यदि आप sysfs में प्रचलित किसी भी cpulist फ़ाइलों पर उस कोड का उपयोग करना चाहते थे, तो "0-7" जैसी स्ट्रिंग हमेशा बहु-प्रोसेसर सिस्टम पर वापस आ जाएगी। फिर किसी दिन, कोई भी एकल कोड पर आपके कोड का उपयोग करता है और सटीक उसी sysfs फ़ाइल को पढ़ता है जिसमें अब "0" एक int देता है।

दूसरे शब्दों में, कोई भी कोड जो उस कोड को कॉल करता है और मूल डेटा प्रकार sysfs (तारों) प्राप्त करने की अपेक्षा करता है, स्पष्ट रूप से str() को डाला जाना चाहिए।

+1

FYI: ['python-sysfs'] (https://github.com/ponycloud/python-sysfs) इस उत्तर के आधार पर मौजूद है। –

संबंधित मुद्दे

 संबंधित मुद्दे