82

我可以更改 Python 脚本的有效进程名称吗?当我获取系统进程列表时,我想显示一个不同的名称而不是进程的真实名称。在 CI 中可以设置

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

但是在 Python 中

argv[0] = "othername"

似乎不起作用。当我获得进程列表(ps ax在我的 linux 框中)时,真实名称不会改变。如果存在,我更喜欢便携式解决方案(或者一个用于 posix 的解决方案和另一个用于 Windows 环境的解决方案)。

提前致谢

4

10 回答 10

91

我最近编写了一个 Python 模块来以可移植的方式更改进程标题:检查https://github.com/dvarrazzo/py-setproctitle

它是 PostgreSQL 用于执行标题更改的代码的包装器。它目前针对 Linux 和 Mac OS X 进行了测试:Windows(功能有限)和 BSD 移植正在进行中。

编辑:截至 2010 年 7 月,该模块适用于 BSD,在 Windows 上功能有限,并且已移植到 Python 3.x。

于 2009-12-08T12:40:46.683 回答
58

实际上,您在 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”:(。但是topps -A显示新的“正在测试”进程名称:)。也killallpkill使用新名称。

顺便说一句,来自 googlecode 的 procname 也会更改argv[0],因此,甚至会更改ps auxf输出。

更新:此答案中发布的解决方案有时在 FreeBSD 上效果不佳。我现在在各种 linux 和 freebsd 机器上使用这个答案中所述的py-setproctitle一年左右。到目前为止没有失败!大家也应该!:)。它使用的代码与PostgreSQL在其主数据库和子进程中使用的代码几乎相同。

于 2009-05-28T20:39:05.810 回答
15

看看setproctitle

这是一个相当便携的版本,适用于许多平台。

pip install setproctitle

 

import setproctitle

setproctitle.setproctitle('new proc title as seen in top')
于 2010-01-05T14:28:37.827 回答
13

简而言之,没有便携的方式。您必须测试系统并使用该系统的首选方法。

此外,我对 Windows 上的进程名称的含义感到困惑。

你的意思是服务名称吗?我想是这样,因为没有其他东西真正有意义(至少对于我的非 Windows 使用大脑而言)。

如果是这样,您需要使用Tim Golden 的 WMI 接口并调用服务上的 .Change 方法......至少根据他的教程

对于 Linux,除了这个为您设置 argv[0] 的包装不佳的模块外,我发现没有任何方法有效。

我什至不知道这是否适用于 BSD 变体(它确实有一个 setproctitle 系统调用)。我很确定 argv[0] 不会在 Solaris 上工作。

于 2009-02-19T12:26:14.997 回答
3

首先,我不确定argv[0]C 程序中的简单设置是否可移植地更改ps. 也许它在某些unixen中确实如此,但我的理解是它并不期望如此。

其次,由于 Windows 特别不兼容 POSIX,因此在 POSIX 和非 POSIX 之间只有少数东西是“可移植的”。由于您特别说“ps”,我假设 POSIX 是您的优先事项,Windows 可能无法正常工作。

更重要的是,我对改变的理解argv[0]是,它需要调用来exec进行这些改变。具体来说,exec调用既有可执行文件的路径,也有单独的argv列表。进行自己的调用可以打破将可执行文件名称放入argv[0].

您拥有操作系统库进程管理,可让您直接访问操作系统库以执行此操作。您应该考虑将您的脚本分成两部分——启动器和“实际工作”。启动器建立运行时环境,并使用所需参数执行实际工作。

在 C 中,您正在用另一个进程替换您自己的进程。在 Python 中,您将使用具有不同 argv[0] 的新解释器替换旧的 Python 解释器。希望它不会因此而犹豫。一些程序检查 argv[0] 来决定他们在做什么。

您还可以使用subprocess.popen设置所需的参数和可执行文件。但是,在这种情况下,父进程应该在子进程完成时逗留以收集子进程。父母可能没有做更多的事情Popen.wait

于 2009-02-19T11:31:25.517 回答
3

我对标记为重复的类似问题的回答:

有更简单的(你不需要导入任何库)但可能不是那么优雅的方式。您必须不要在 shebang 行内使用“env”。

换句话说,这将在进程列表中命名为“python”:

#!/usr/bin/env python

但这将以您的脚本名称命名:

#!/usr/bin/python

所以你可以用类似的东西找到pidof -x scriptnameps -C scriptname

于 2015-11-25T09:12:35.097 回答
2

我发现python-prctl在 Linux 下工作得很好。您将不得不为 Windows 找到其他东西。

于 2011-02-07T15:45:35.020 回答
0

如果你只需要支持 Linux 并且只需要更改进程名称,那么你可以简单地将其写入/proc/self/comm.

例子:

import os
import subprocess

print(subprocess.run(['pidof', 'foo'], stdout=subprocess.PIPE,
        universal_newlines=True))
print(subprocess.check_output(['ps', 'p', str(os.getpid()), '-o', 'pid,comm,cmd'],
        universal_newlines=True))

with open(f'/proc/self/comm', 'w') as f:
    f.write('foo')

print(subprocess.check_output(['pidof', 'foo'], universal_newlines=True))
print(subprocess.check_output(['ps', 'p', str(os.getpid()), '-o', 'pid,comm,cmd'],
    universal_newlines=True))

输出:

$ python3 test.py argone argtwo
CompletedProcess(args=['pidof', 'foo'], returncode=1, stdout='')
    PID COMMAND         CMD
2881003 python3 test.py python3 test.py argone argtwo

2881003

    PID COMMAND         CMD
2881003 foo             python3 test.py argone argtwo

注意:在 Linux 上,在 C 程序中,写入 toargv[0]只是更改参数in/proc/self/cmdline不是/proc/self/comm. 因此,它不会影响COMMAND 列、pidofCOMMAND列、plain等。toppspgrep


setproctitle包支持多个平台,并且 - 在 Linux 上 - 更改命令和参数向量。但是,它是 C 扩展。

于 2021-07-24T09:43:47.980 回答
-1

Windows 上的一个超级 hack 是复制 python.exe,将其重命名为 process_name.exe,使用重命名的 python 调用您的脚本。

它是一个超级 hacky,但由于 Windows 上没有简单的解决方案,如果一个人只需要快速完成它以便一个脚本能够监控它,它是一个公平的选择。

从理论上讲,它甚至可以编写脚本……超级骗子黑客!?

于 2021-11-25T16:04:24.823 回答
-21
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

注意单个“=”符号

于 2009-02-19T10:39:53.130 回答