Is there a way to change effective process name in Python?

71,664

Solution 1

Simply put, there's no portable way. You'll have to test for the system and use the preferred method for that system.

Further, I'm confused about what you mean by process names on Windows.

Do you mean a service name? I presume so, because nothing else really makes any sense (at least to my non-Windows using brain).

If so, you need to use Tim Golden's WMI interface and call the .Change method on the service... at least according to his tutorial.

For Linux none of the methods I found worked except for this poorly packaged module that sets argv[0] for you.

I don't even know if this will work on BSD variants (which does have a setproctitle system call). I'm pretty sure argv[0] won't work on Solaris.

Solution 2

I've recently written a Python module to change the process title in a portable way: check https://github.com/dvarrazzo/py-setproctitle

It is a wrapper around the code used by PostgreSQL to perform the title change. It is currently tested against Linux and Mac OS X: Windows (with limited functionality) and BSD portings are on the way.

Edit: as of July 2010, the module works with BSD and with limited functionality on Windows, and has been ported to Python 3.x.

Solution 3

actually you need 2 things on linux: modify argv[0] from C (for ps auxf and friends) and call prctl with PR_SET_NAME flag.

There is absolutely no way to do first piece from python itself. Although, you can just change process name by calling prctl.

def set_proc_name(newname):
    from ctypes import cdll, byref, create_string_buffer
    libc = cdll.LoadLibrary('libc.so.6')
    buff = create_string_buffer(len(newname)+1)
    buff.value = newname
    libc.prctl(15, byref(buff), 0, 0, 0)

def get_proc_name():
    from ctypes import cdll, byref, create_string_buffer
    libc = cdll.LoadLibrary('libc.so.6')
    buff = create_string_buffer(128)
    # 16 == PR_GET_NAME from <linux/prctl.h>
    libc.prctl(16, byref(buff), 0, 0, 0)
    return buff.value

import sys
# sys.argv[0] == 'python'

# outputs 'python'
get_proc_name()

set_proc_name('testing yeah')

# outputs 'testing yeah'
get_proc_name()

ps auxf will show just 'python' after that :(. But top and ps -A will show new 'testing yeah' process name :). Also killall and pkill will work with new name.

btw, procname from googlecode also changes argv[0], thus, even, changes ps auxf output.

UPDATE: The solution posted in this answer does not play nice sometimes on FreeBSD. I'm now using py-setproctitle stated in this answer for a year or so on various linux and freebsd boxes. No fails so far! Everybody should too! :). It uses almost the same code as PostgreSQL uses in its main database and child processes.

Solution 4

Have a look on setproctitle package

This is quite a portable version and works on many platforms.

pip install setproctitle

 

import setproctitle

setproctitle.setproctitle('new proc title as seen in top')

Solution 5

First, I'm not sure that simply settings argv[0] in a C program portably changes the name shown in ps. Maybe it does in some unixen, but my understanding is that it's not expected to.

Second, since Windows is specifically non-POSIX compliant, only a few things are "portable" between POSIX and non-POSIX. Since you specifically say 'ps', I'll assume that POSIX is your priority and Windows may not work.

More importantly, my understanding of changing argv[0] is that it requires a call to exec to make these changes. Specifically, the exec call has both a path to an executable and a separate argv list. Making your own call allows you to break the shell convention of putting the executable name in argv[0].

You have OS library process management which gives you direct access to the OS library for doing this. You should consider breaking your script into two parts -- a starter and the "real work". The starter establishes the run-time environment and exec's the real work with the desired parameters.

In C, you're replacing your own process with another. In Python, you're replacing the old Python interpreter with a new one that has a different argv[0]. Hopefully, it won't balk at this. Some programs check argv[0] to decide what they're doing.

You also have subprocess.popen that you can use to set your desired args and executable. In this case, however, the parent process should lingers around to collect the child when the child finishes. The parent may not be doing anything more than a Popen.wait

Share:
71,664

Related videos on Youtube

Emilio
Author by

Emilio

Updated on July 05, 2022

Comments

  • Emilio
    Emilio almost 2 years

    Can I change effective process name of a Python script? I want to show a different name instead of the real name of the process when I get the system process list. In C I can set

    strcpy(argv[0],"othername");
    

    But in Python

    argv[0] = "othername"
    

    doesn't seem to work. When i get process list (with ps ax in my linux box) the real name doesn't change. I prefer a portable solution (or else one solution for posix and another for windows environments), if it exists.

    Thanks in advance

    • anarcat
      anarcat over 8 years
    • Basj
      Basj over 5 years
      Is there a solution nowadays for Windows? (maybe with Python 3.x?) More precisely: The "Windows Task Manager" (CTRL+SHIFT+ESCAPE), tab "Processes", should display a custom string in the first column "Image Name" rather than just python.exe or pythonw.exe. NB: another solution than duplicating python.exe to mycustomstring.exe ;)
  • Emilio
    Emilio over 15 years
    But if i run ps (process list in linux boxes) the process name remain exactly the same. Try
  • Glenn Maynard
    Glenn Maynard over 14 years
    No, changing argv in Linux (and likely other Unixes, but not all) does immediately change the visible process name, which is used by many widely-used programs to give descriptive names for their processes: both ssh and postgres do this, and some actively change their name on the fly to indicate their current status. A Python module could be written to do this, using the Py_GetArgcArgv API call.
  • user
    user over 10 years
    Can't install on windows.
  • piro
    piro over 10 years
    @user never mind: it isn't very helpful on Windows but there's not much to do about it.
  • KillianDS
    KillianDS over 10 years
    Is there a way to change the arguments displayed by ps -f? I don't really care about the program name (always python), but I want to change the displayed arguments.
  • piro
    piro over 10 years
    @KillianDS: do you mean you want the output of "ps -f" different from the one of "ps"? You can't have it afaik.
  • bufh
    bufh about 9 years
    I know it's late, but for new readers, consider also @MattWritesCode answer, quick and simple for CPython on Linux.
  • Dakkaron
    Dakkaron about 7 years
    This does not change the process name at all. It only changes Python's copy of argv. I would recommend deleting this obviously wrong answer.
  • radtek
    radtek over 6 years
    procname doesn't work on PyPy (only on CPython) have to use setproctitle.
  • Bachsau
    Bachsau about 6 years
    That is not a Python module. It is a C module.
  • Christopher Barber
    Christopher Barber about 5 years
    On Mac OSX this works for ps but not for top or the Activity Monitor.
  • David Parks
    David Parks over 4 years
    Beautiful simple solution here.
  • MisterMiyagi
    MisterMiyagi almost 4 years
    This does not appear to change the equivalent of psutil.Process.name on MacOS 10.14, but works on RHEL 7.
  • Frederic
    Frederic over 3 years
    Works on Linux perfectly. Does not really work on Windows, and acknowledged as such by the doc of setproctitle. A true Windows solution is most likely difficult.
  • maxschlepzig
    maxschlepzig almost 3 years
    An equivalent and simpler implementation of your functions is to just write/read /proc/self/comm. See also: stackoverflow.com/a/68508813/427158