a class that gets available, running, and stopped services (Ubuntu/Debian) - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: General (https://python-forum.io/forum-1.html) +--- Forum: Code sharing (https://python-forum.io/forum-5.html) +--- Thread: a class that gets available, running, and stopped services (Ubuntu/Debian) (/thread-12457.html) |
a class that gets available, running, and stopped services (Ubuntu/Debian) - rootVIII - Aug-25-2018 #! /usr/bin/python3 import os class ServiceReport: def __init__(self): self.services = [] self.all_services = [] self.stopped_services = [] self.running_services = [] self.srvc_cmd = "service --status-all &> /dev/null" self.set_services() self.extract_services() def set_services(self): self.services = os.popen(self.srvc_cmd) def get_all_services(self): return self.all_services def get_running_services(self): return self.running_services def get_stopped_services(self): return self.stopped_services def running_services_count(self): return len(self.running_services) def stopped_services_count(self): return len(self.stopped_services) def all_services_count(self): return len(self.all_services) def extract_services(self): for service in sorted(self.services): self.all_services.append(service[8:-1]) if "+" in service: self.running_services.append(service[8:-1]) else: self.stopped_services.append(service[8:-1]) if __name__ == "__main__": sr = ServiceReport() print("\n" + str(sr.all_services_count()) + " services are available") for x in sr.get_all_services(): print(x) print("\n" + str(sr.running_services_count()) + " services are running") for y in sr.get_running_services(): print(y) print("\n" + str(sr.stopped_services_count()) + " services are stopped") for z in sr.get_stopped_services(): print(z) RE: a class that gets available, running, and stopped services (Ubuntu/Debian) - Gribouillis - Aug-25-2018 I would rather return a sequence of small Service objects for such a program, because Python is very strong at manipulating collections and I think it opens more flexible possibilities. Here is a proposal from collections import namedtuple import os class Service(namedtuple('Service', 'name status')): __slots__ = () def is_running(self): return self.status == '+' def is_stopped(self): return self.status == '-' def has_no_status(self): return self.status == '?' def service_status_all(): for line in os.popen("service --status-all &> /dev/null"): _, status, _, name = line.strip().split() yield Service(name, status) if __name__ == '__main__': services = list(service_status_all()) print("{} services are available".format(len(services))) for x in services: print(x.name) running = [s for s in services if s.is_running()] print() print("{} services are running".format(len(running))) for y in running: print(y.name) stopped = [s for s in services if s.is_stopped()] print() print("{} services are stopped".format(len(stopped))) for y in stopped: print(y.name) RE: a class that gets available, running, and stopped services (Ubuntu/Debian) - rootVIII - Aug-25-2018 Ah I like the yield keyword. I actually attempted to use that as the service command seems to gradually output the services. I couldn’t get it to work. I’m glad you posted that to see how to return an iterator correctly RE: a class that gets available, running, and stopped services (Ubuntu/Debian) - rootVIII - Aug-26-2018 Just out of curiosity... I noticed that you used the "?" in case of no status... does the output of service --status-all on your machine give a service/status that does not have a [+] or a [-]? RE: a class that gets available, running, and stopped services (Ubuntu/Debian) - Gribouillis - Aug-26-2018 (Aug-26-2018, 01:32 AM)rootVIII Wrote: does the output of service --status-all on your machine give a service/status that does not have a [+] or a [-]?They all have [ + ] or [ - ] , however man service indicatesQuote: service --status-all runs all init scripts, in alphabetical order, with the status It could be a good idea to parse more seriously the lines of output in case the syntax of service --status-all changes. The re module can be used for this. Also the command can be made a classmethod of the Service class, which would allow further code to subclass the Service classfrom collections import namedtuple import os import re class Service(namedtuple('Service', 'name status')): __slots__ = () def is_running(self): return self.status == '+' def is_stopped(self): return self.status == '-' def has_no_status(self): return self.status == '?' @classmethod def iterate_all(cls): for line in os.popen("service --status-all &> /dev/null"): match = re.match( r"\[\s*(?P<status>[-+?])\s*\]\s*(?P<name>[^\s].+)", line.strip()) if not match: raise ValueError(('Unknown service status syntax:', line)) yield cls(match.group('name'), match.group('status')) if __name__ == '__main__': for service in Service.iterate_all(): print(service) RE: a class that gets available, running, and stopped services (Ubuntu/Debian) - rootVIII - Aug-26-2018 Yes thank you:) |