Search code examples
pythonlinuxpsutil

How to list daemon (services) process in linux, as with psutil?


I am trying to print the current running services (daemon process?) in linux using psutil

In windows, using psutil I can get the currently running services with this code:

def log(self):
        win_sev = set()
        for sev in psutil.win_service_iter():
            if sev.status() == psutil.STATUS_RUNNING:
                win_sev.add(sev.display_name())
        return win_sev

I want to get the same effect in linux, I tried using the subprocess module and POPEN


 command = ["service", "--status-all"]  # the shell command
 p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)        
 result = p.communicate()[0]
 print result

However I would like to know if I can get the same result using psutil, I tried using the

psutil.pids()

But this only shows

python
init
bash

But when I run service --status-all I get a much bigger list including apache,sshd....

Thanks


Solution

  • The service command in WSL shows Windows services. As we've determined (in in-comment discussion) that you're trying to list Linux services, and using WSL only as a test platform, this answer is written to apply to the majority of Linux distributions, rather than to WSL.


    The following will work on Linux distros using systemd as their init system (this applies to most modern distros -- including current releases of Arch, NixOS, Fedora, RHEL, CentOS, Debian, Ubuntu, etc). It will not work on WSL -- at least, not the version you quoted, which does not appear to be using systemd as its init system.

    #!/usr/bin/env python
    
    import re
    import psutil
    
    def log_running_services():
        known_cgroups = set()
        for pid in psutil.pids():
            try:
                cgroups = open('/proc/%d/cgroup' % pid, 'r').read()
            except IOError:
                continue # may have exited since we read the listing, or may not have permissions
            systemd_name_match = re.search('^1:name=systemd:(/.+)$', cgroups, re.MULTILINE)
            if systemd_name_match is None:
                continue # not in a systemd-maintained cgroup
            systemd_name = systemd_name_match.group(1)
            if systemd_name in known_cgroups:
                continue # we already printed this one
            if not systemd_name.endswith('.service'):
                continue # this isn't actually a service
            known_cgroups.add(systemd_name)
            print(systemd_name)
    
    if __name__ == '__main__':
        log_running_services()