有没有办法在Python中更改有效的进程名称?


78

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

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

但是在Python中

argv[0] = "othername"

似乎不起作用。当我获得进程列表(ps ax在Linux框中带有)时,真实姓名不变。如果存在的话,我更喜欢一种便携式解决方案(或者针对posix的一种解决方案,以及针对Windows环境的另一种解决方案)。

提前致谢



如今Windows是否有解决方案?(也许使用Python 3.x?)更准确地说:“ Windows任务管理器”(CTRL + SHIFT + ESCAPE)选项卡“进程”应该在第一列“图像名称”中显示自定义字符串,而不仅仅是python.exe或pythonw.exe。注意:除了将python.exe复制到mycustomstring.exe之外,另一种解决方案是;)
巴吉(

Answers:


13

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

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

您的意思是服务名称吗?我猜想是这样,因为其他任何事情都没有任何意义(至少对于我使用Windows的非Windows用户而言)。

如果是这样,则需要使用Tim Golden的WMI界面并在服务上调用.Change方法……至少根据他的教程

对于Linux,我发现没有一种方法可以工作,除了这个包装差的模块会为您设置argv [0]。

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


我知道已经晚了,但是对于新读者来说,也请考虑@MattWritesCode answer,对于Linux上的CPython而言,它是快速而简单的。
bufh

86

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

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

编辑:从2010年7月开始,该模块可与BSD一起使用,并且在Windows上具有有限的功能,并且已移植到Python3.x。


无法在Windows上安装。
用户

@user没关系:它在Windows上不是很有用,但是没有太多要做。
piro

有没有办法更改ps -f显示的参数?我不太在乎程序名称(总是python),但是我想更改显示的参数。
KillianDS 2014年

1
@KillianDS:您是说要让“ ps -f”的输出与“ ps”之一的输出不同吗?你不能拥有它afaik。
2014年

那不是Python模块。它是一个C模块。
Bachsau

56

实际上,在Linux上,您需要做两件事:argv[0]C(对于ps auxf和朋友)进行修改,并prctlPR_SET_NAMEflag调用。

绝对没有办法从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将显示只是:(后“蟒蛇”,但topps -A将显示新的“测试啊”进程名:)。还killallpkill将与新名称的工作。

顺便说一句,googlecode的procname也会更改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
美丽的简单解决方案在这里。
David Parks

4

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

其次,由于Windows特别不兼容POSIX,因此在POSIX和非POSIX之间只有几件事是“可移植的”。由于您专门说“ ps”,因此我假定POSIX是您的优先事项,并且Windows可能无法正常工作。

更重要的是,我对变更的理解argv[0]是它需要exec进行更改。具体来说,该exec调用既有指向可执行文件的路径,又有单独的argv列表。进行自己的调用可让您打破将可执行文件名称放入中的shell约定argv[0]

您具有OS库进程管理,可以直接访问OS库来执行此操作。您应该考虑将脚本分为两部分-入门和“实际工作”。启动程序将建立运行时环境,并使用所需的参数执行实际工作。

在C语言中,您将自己的过程替换为另一个过程。在Python中,您要用具有不同argv [0]的新Python解释器替换旧的Python解释器。希望它不会对此感到沮丧。一些程序检查argv [0]来确定它们在做什么。

您还具有subprocess.popen,可用于设置所需的args和可执行文件。但是,在这种情况下,当孩子完成工作时,父进程应该徘徊以收集孩子。父母可能只做一件事Popen.wait


1
不,在Linux(可能还有其他Unix,但不是全部)上更改argv确实会立即更改可见的进程名称,许多广泛使用的程序使用它来为其进程提供描述性名称:ssh和postgres都这样做,有些即时动态更改其名称以指示其当前状态。可以使用Py_GetArgcArgv API调用编写Python模块来实现此目的。
格伦·梅纳德

3

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

有一个更简单的方法(您不需要导入任何库),但也许不是那么优雅的方法。您不必在shebang行内使用“ env”。

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

#!/usr/bin/env python

但这将用您的脚本名命名:

#!/usr/bin/python

这样您就可以找到类似pidof -x scriptnameps -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框中的进程列表),则进程名称保持完全相同。试试
Emilio

10
这根本不会更改进程名称。它仅更改Python的argv副本。我建议删除此明显错误的答案。
达卡龙
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.