pythoncommand-lineprocessaccess-deniedpsutil

Python: how to avoid psutil.process_iter() 'AccessDenied' and other misc errors?


In Python, why am I seeing psutil.AccessDenied errors/exceptions when iterating through my processes (which works just fine) and printing their command lines via psutil.cmdline() (which, frustratingly experiences the aforementioned Exception for the exact same process, where psutil.name() works fine), as per the following code snippet?

import psutil
for proc in psutil.process_iter():
    print (proc.name())    # seems to consistently work
    print (proc.cmdline()) # sometimes generates Exception

Solution

  • Apparently Python (or at least my python v3.11.2, macOS v12.6.3 system) lets you iterate through all the OS/system's processes, but prevents you from reading the cmdline of all the processes, even if it lets you read the "base name" of the process of cmdline-problematic processes. More details.

    So catch and bypass the exception:

        try:
            cmdline = proc.cmdline()
        except psutil.AccessDenied:
            continue
    

    Full, working script (on my above macOS system):

    #!/usr/bin/env python3
    import psutil, logging
    log = logging.getLogger()
    
    # psutil all-processes iteration:
    # https://stackoverflow.com/a/4230226/605356
    for proc in psutil.process_iter():
        # avoid erroring on proc.cmdline() + psutil.AccessDenied Exception,
        # even though proc.name() experiences no issue:
        # https://www.florianreinhard.de/2022-02-28/accessdenied-in-psutil/
        try:
            cmdline = proc.cmdline()
        except psutil.AccessDenied:
            continue
        except (psutil.ZombieProcess, psutil.NoSuchProcess):
            # these Exceptions also happen a lot on my
            # macOS v12.6.3, python v3.11.2 system
            continue
        except Exception as e: # optional and use with care;
                               # see https://stackoverflow.com/q/4990718/605356
            log.exception("something is wrong: " + ' '.join(cmdline))
            continue
        print('name = ' + proc.name())
        print('cmdl = ' + ' '.join(cmdline))