Чи є спосіб змінити ефективну назву процесу в Python?


78

Чи можу я змінити ефективну назву процесу сценарію Python? Я хочу показати інше ім’я замість справжнього імені процесу, коли отримую список системних процесів. У CI можна встановити

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

Але в Python

argv[0] = "othername"

здається, не працює. Коли я отримую список процесів ( ps axу моєму вікні Linux), справжнє ім'я не змінюється. Я вважаю за краще портативне рішення (або одне рішення для posix, а інше для середовищ Windows), якщо воно існує.

Спасибі заздалегідь


Дивись також superuser.com/questions/427642 / ... , де bugs.python.org/issue5672 це згадувалося
anarcat

1
Чи є сьогодні рішення для Windows? (можливо, з Python 3.x?) Точніше: "Диспетчер завдань Windows" (CTRL + SHIFT + ESCAPE), вкладка "Процеси", повинен відображати власний рядок у першому стовпці "Ім'я зображення", а не просто python.exe або pythonw.exe. NB: інше рішення, ніж дублювання python.exe на mycustomstring.exe;)
Basj

Відповіді:


13

Простіше кажучи, портативного способу немає. Вам доведеться протестувати систему та скористатися найкращим методом для цієї системи.

Крім того, мене бентежить, що ви маєте на увазі під іменами процесів у Windows.

Ви маєте на увазі назву послуги? Я так припускаю, бо ніщо інше насправді не має жодного сенсу (принаймні для мого не-Windows, що використовує мозок).

Якщо так, вам потрібно скористатися інтерфейсом WMI Тіма Голдена та викликати метод .Change на сервісі ... принаймні згідно з його підручником .

У Linux жоден із методів, який я знайшов, не працював, за винятком цього погано упакованого модуля, який встановлює для вас argv [0].

Я навіть не знаю, чи це буде працювати на варіантах BSD (який має системний виклик setproctitle). Я впевнений, що argv [0] не працюватиме на Solaris.


Я знаю, що пізно, але для нових читачів розгляньте також відповідь @MattWritesCode , швидку та просту для CPython в Linux.
bufh

86

Нещодавно я писав модуль Python для перенесення назви процесу у портативний спосіб: перевірте https://github.com/dvarrazzo/py-setproctitle

Це обгортка коду, що використовується PostgreSQL для зміни заголовка. В даний час він тестується на Linux та Mac OS X: на шляху є порти Windows (з обмеженими функціональними можливостями) та BSD.

Редагувати: станом на липень 2010 року модуль працює з BSD і з обмеженими функціональними можливостями в Windows, і його було перенесено на Python 3.x.


Не вдається встановити на Windows.
користувач

@user неважливо: це не дуже корисно для Windows, але з цим багато не можна зробити.
piro

Чи є спосіб змінити аргументи, що відображаються ps -f? Мене насправді не хвилює назва програми (завжди python), але я хочу змінити відображені аргументи.
KillianDS

1
@KillianDS: ти маєш на увазі, що хочеш, щоб результат "ps -f" відрізнявся від результату "ps"? Ви не можете мати це afaik.
piro

Це не модуль Python. Це модуль C.
Бахсау,

56

насправді вам потрібні дві речі в Linux: змінити argv[0]з C(для ps auxfі для друзів) і зателефонувати за prctlдопомогоюPR_SET_NAME прапором.

Абсолютно ніяк не можна зробити перший шматок із самого python. Хоча ви можете просто змінити назву процесу, зателефонувавши 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після цього покаже лише "python" :(. Але topі ps -Aпокаже нову назву процесу "тестування так" :). Також killallіpkill буде працювати з новим ім'ям.

До речі, procname з googlecode також змінюється argv[0], таким чином, навіть, змінює ps auxfрезультат.

ОНОВЛЕННЯ : Рішення, розміщене у цій відповіді, часом не виглядає приємно на FreeBSD. Зараз я використовую py-setproctitle, зазначений у цій відповіді, близько року на різних полях Linux та freebsd. Поки що не вдається! Кожен також повинен! :). Він використовує майже той же код, PostgreSQL використовує в своїх основних процесів бази даних і дитини.


procname не працює на PyPy (лише на CPython), потрібно використовувати setproctitle.
radtek

13

Погляньте на setproctitle пакет

Це досить портативна версія і працює на багатьох платформах.

pip install setproctitle

 

import setproctitle

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

1
Прекрасне просте рішення тут.
Девід Паркс,

Чудово працює на Linux. Насправді не працює на Windows, і визнаний таким як документ setproctitle. Справжнє рішення для Windows, швидше за все, важко.
Фредерік

4

По-перше, я не впевнений, що просто налаштування argv[0]програми C переносять змінне ім'я, вказане в ps. Можливо, це відбувається в деяких Unixen, але я розумію, що це не очікується.

По-друге, оскільки Windows спеціально не сумісний з POSIX, лише кілька речей є "портативними" між POSIX та non-POSIX. Оскільки ви спеціально говорите "ps", я припускаю, що POSIX є вашим пріоритетом, і Windows може не працювати.

Що ще важливіше, моє розуміння змін argv[0]полягає в тому, що execдля здійснення цих змін потрібен заклик . Зокрема, execвиклик має як шлях до виконуваного файлу, так і окремий argvсписок. Здійснення власного виклику дозволяє вам порушити домовленість оболонки про введення виконуваного імені argv[0].

У вас є управління процесами бібліотеки ОС яке дає вам прямий доступ до бібліотеки ОС для цього. Вам слід подумати про розбиття вашого сценарію на дві частини - початкову і "справжню роботу". Стартер встановлює середовище виконання і виконує реальну роботу з бажаними параметрами.

У C ви замінюєте власний процес іншим. У Python ви замінюєте старий інтерпретатор Python новим, який має інший argv [0]. Будемо сподіватися, що це не завадить. Деякі програми перевіряють argv [0], щоб вирішити, що вони роблять.

У вас також є subprocess.popen, за допомогою якого ви можете встановити потрібні аргументи та виконуваний файл. Однак у цьому випадку батьківський процес повинен тривати, щоб забрати дитину, коли дитина закінчить. Можливо, батько не робить нічого більше, ніж aPopen.wait


1
Ні, зміна argv в Linux (і, мабуть, інших Unix, але не всіх) відразу змінює видиме ім’я процесу, яке використовується багатьма широко використовуваними програмами для надання описових назв своїх процесів: це роблять і ssh, і postgres, а деякі активно змінювати своє ім’я на льоту, щоб вказати їх поточний статус. Для цього можна написати модуль Python, використовуючи виклик API Py_GetArgcArgv.
Гленн Мейнард,

3

Моя відповідь на подібне запитання, позначене як дублікат :

Існує простіше (вам не потрібно імпортувати будь-які бібліотеки), але, можливо, не так елегантно. Ви не повинні використовувати "env" всередині лінії shebang.

Іншими словами, це буде називатися "python" у списку процесів:

#!/usr/bin/env python

Але це буде називатися з вашим ім'ям сценарію:

#!/usr/bin/python

Тож ви зможете знайти його з чимось на зразок pidof -x scriptnameабоps -C scriptname



-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

Зверніть увагу на єдиний знак '='


3
Але якщо я запускаю ps (список процесів у вікнах Linux), назва процесу залишається абсолютно незмінною. Спробуйте
Еміліо

10
Це зовсім не змінює назву процесу. Це лише змінює копію argv Python. Я б рекомендував видалити цю очевидно неправильну відповідь.
Даккарон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.