¿Hay alguna forma de cambiar el nombre del proceso efectivo en Python?

78

¿Puedo cambiar el nombre de proceso efectivo de una secuencia de comandos de Python? Quiero mostrar un nombre diferente en lugar del nombre real del proceso cuando obtengo la lista de procesos del sistema. En CI se puede configurar

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

Pero en Python

argv[0] = "othername"

no parece funcionar. Cuando obtengo la lista de procesos ( ps axen mi cuadro de Linux), el nombre real no cambia. Prefiero una solución portátil (o una solución para posix y otra para entornos Windows), si existe.

Gracias por adelantado

Emilio
fuente
ver también superuser.com/questions/427642/...~~V~~3rd , donde bugs.python.org/issue5672 se ve mencionado
anarcat
1
¿Existe una solución hoy en día para Windows? (¿Quizás con Python 3.x?) Más precisamente: La pestaña "Procesos" del "Administrador de tareas de Windows" (CTRL + MAYÚS + ESCAPE) debería mostrar una cadena personalizada en la primera columna "Nombre de imagen" en lugar de solo python.exe o pythonw.exe. NB: otra solución que duplicar python.exe en mycustomstring.exe;)
Basj

Respuestas:

13

En pocas palabras, no existe una forma portátil. Tendrá que probar el sistema y utilizar el método preferido para ese sistema.

Además, estoy confundido acerca de lo que quiere decir con nombres de procesos en Windows.

¿Te refieres a un nombre de servicio? Supongo que sí, porque nada más realmente tiene sentido (al menos para mi cerebro que no usa Windows).

Si es así, debe usar la interfaz WMI de Tim Golden y llamar al método .Change en el servicio ... al menos de acuerdo con su tutorial .

Para Linux, ninguno de los métodos que encontré funcionó a excepción de este módulo mal empaquetado que establece argv [0] para usted.

Ni siquiera sé si esto funcionará en variantes de BSD (que tiene una llamada al sistema setproctitle). Estoy bastante seguro de que argv [0] no funcionará en Solaris.

Van Gale
fuente
Sé que es tarde, pero para los nuevos lectores, considere también la respuesta de @MattWritesCode , rápida y simple para CPython en Linux.
bufh
86

Recientemente escribí un módulo de Python para cambiar el título del proceso de forma portátil: consulte https://github.com/dvarrazzo/py-setproctitle

Es un envoltorio alrededor del código utilizado por PostgreSQL para realizar el cambio de título. Actualmente se prueba con Linux y Mac OS X: Windows (con funcionalidad limitada) y las adaptaciones BSD están en camino.

Editar: a partir de julio de 2010, el módulo funciona con BSD y con funcionalidad limitada en Windows, y se ha adaptado a Python 3.x.

piro
fuente
No se puede instalar en Windows.
usuario
@user no importa: no es muy útil en Windows, pero no hay mucho que hacer al respecto.
piro
¿Hay alguna forma de cambiar los argumentos mostrados por ps -f? Realmente no me importa el nombre del programa (siempre python), pero quiero cambiar los argumentos mostrados.
KillianDS
1
@KillianDS: ¿quieres decir que quieres que la salida de "ps -f" sea diferente a la de "ps"? No puedes tenerlo afaik.
piro
Ese no es un módulo de Python. Es un módulo de C.
Bachsau
56

en realidad, necesitas 2 cosas en Linux: modificar argv[0]desde C(para ps auxfy amigos) y llamar prctlcon PR_SET_NAMEbandera.

No hay absolutamente ninguna forma de hacer la primera pieza desde Python. Aunque, puede cambiar el nombre del proceso llamando a 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 auxfmostrará solo 'python' después de eso :(. Pero topy ps -Amostrará un nuevo nombre de proceso 'testing sí' :). También killally pkillfuncionará con nuevo nombre.

por cierto, procname de googlecode también cambia argv[0], por lo tanto, incluso, cambia la ps auxfsalida.

ACTUALIZACIÓN : La solución publicada en esta respuesta no funciona bien a veces en FreeBSD. Ahora estoy usando py-setproctitle indicado en esta respuesta durante un año más o menos en varias cajas de linux y freebsd. ¡No falla hasta ahora! ¡Todos deberían también! :). Utiliza casi el mismo código que utiliza PostgreSQL en su base de datos principal y procesos secundarios.

Vadim Fint
fuente
procname no funciona en PyPy (solo en CPython) tiene que usar setproctitle.
radtek
13

Eche un vistazo al paquete setproctitle

Esta es una versión bastante portátil y funciona en muchas plataformas.

pip install setproctitle

 

import setproctitle

setproctitle.setproctitle('new proc title as seen in top')
Valgog
fuente
1
Hermosa solución simple aquí.
David Parks
Funciona perfectamente en Linux. Realmente no funciona en Windows, y lo reconoce el documento de setproctitle. Una verdadera solución de Windows probablemente sea difícil.
Frederic
4

Primero, no estoy seguro de que simplemente la configuración argv[0]en un programa C cambie de manera portátil el nombre que se muestra en ps. Tal vez lo haga en algún unixen, pero tengo entendido que no se espera que lo haga.

En segundo lugar, dado que Windows no es compatible específicamente con POSIX, solo algunas cosas son "portátiles" entre POSIX y no POSIX. Dado que dice específicamente 'ps', asumiré que POSIX es su prioridad y que Windows puede no funcionar.

Más importante aún, mi comprensión del cambio argv[0]es que requiere un llamado execpara realizar estos cambios. Específicamente, la execllamada tiene una ruta a un ejecutable y una argvlista separada . Hacer su propia llamada le permite romper la convención de shell de poner el nombre del ejecutable argv[0].

Tiene una gestión de procesos de la biblioteca del sistema operativo que le da acceso directo a la biblioteca del sistema operativo para hacer esto. Debería considerar dividir su guión en dos partes: un comienzo y el "trabajo real". El arrancador establece el entorno de tiempo de ejecución y el ejecutivo realiza el trabajo real con los parámetros deseados.

En C, está reemplazando su propio proceso por otro. En Python, está reemplazando el antiguo intérprete de Python por uno nuevo que tiene un argv [0] diferente. Con suerte, no se resistirá a esto. Algunos programas comprueban argv [0] para decidir qué están haciendo.

También tiene subprocess.popen que puede usar para configurar los argumentos y ejecutables que desee. En este caso, sin embargo, el proceso principal debe demorarse para recoger al niño cuando el niño termina. Es posible que el padre no esté haciendo nada más que unPopen.wait

S. Lot
fuente
1
No, cambiar argv en Linux (y probablemente otros Unix, pero no todos) cambia inmediatamente el nombre del proceso visible, que es utilizado por muchos programas ampliamente utilizados para dar nombres descriptivos a sus procesos: tanto ssh como postgres hacen esto, y algunos cambiar activamente su nombre sobre la marcha para indicar su estado actual. Se podría escribir un módulo de Python para hacer esto, usando la llamada a la API Py_GetArgcArgv.
Glenn Maynard
3

Mi respuesta a una pregunta similar marcada como duplicada :

Hay una forma más simple (no necesita importar ninguna biblioteca) pero tal vez no sea tan elegante. No tienes que usar "env" dentro de la línea shebang.

En otras palabras, esto se denominará "python" en la lista de procesos:

#!/usr/bin/env python

Pero esto se nombrará con su nombre de script:

#!/usr/bin/python

Entonces podrás encontrarlo con algo como pidof -x scriptnameops -C scriptname

Sasha Ru
fuente
2

He descubierto que python-prctl funciona muy bien en Linux. Tendrá que encontrar algo más para Windows.

Vukasin Toroman
fuente
-18
In [1]: import sys

In [2]: print sys.argv[0]
C:\Python25\scripts\ipython.py

In [3]: sys.argv[0] = 'foo'

In [4]: print sys.argv[0]
foo

Tenga en cuenta el signo único '='

Boris Gorelik
fuente
3
Pero si ejecuto ps (lista de procesos en cajas de Linux), el nombre del proceso sigue siendo exactamente el mismo. Prueba
Emilio
10
Esto no cambia el nombre del proceso en absoluto. Solo cambia la copia de argv de Python. Recomendaría eliminar esta respuesta obviamente incorrecta.
Dakkaron