我可以更改Python脚本的有效进程名称吗?当我获得系统进程列表时,我想显示一个不同的名称而不是进程的真实名称。在C中我可以设置
strcpy(argv[0],"othername");
但是在Python中
argv[0] = "othername"
似乎不起作用。当我获得进程列表(在我的linux框中使用ps ax
)时,真实姓名不会改变。我更喜欢便携式解决方案(或者一个用于posix的解决方案和另一个用于Windows环境的解决方案),如果它存在的话。
提前致谢
答案 0 :(得分:80)
我最近编写了一个Python模块,以便携式方式更改流程标题:检查https://github.com/dvarrazzo/py-setproctitle
它是PostgreSQL用于执行标题更改的代码的包装器。它目前针对Linux和Mac OS X进行了测试:Windows(功能有限)和BSD移植正在进行中。
编辑:截至2010年7月,该模块与BSD配合使用,在Windows上功能有限,并已移植到Python 3.x.
答案 1 :(得分:50)
实际上你需要在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
也可以使用新名称。
btw,来自googlecode的procname也会更改argv[0]
,因此,甚至会更改ps auxf
输出。
更新:此答案中发布的解决方案有时在FreeBSD上效果不佳。我现在使用py-setproctitle陈述in this answer一年左右的各种linux和freebsd框。到目前为止没有失败!每个人都应该! :)。它在其主数据库和子进程中使用与PostgreSQL uses几乎相同的代码。
答案 2 :(得分:13)
简单地说,没有可移植的方式。您必须测试系统并使用该系统的首选方法。
此外,我对Windows上的进程名称的含义感到困惑。
你的意思是服务名称?我认为是这样,因为没有别的东西真的有意义(至少对我的非Windows使用大脑)。
如果是这样,您需要使用Tim Golden's WMI interface并在服务上调用.Change方法...至少根据他的tutorial。
对于Linux,除了为您设置argv [0]的this poorly packaged module之外,我找不到任何方法。
我甚至不知道这是否适用于BSD变体(它有一个setproctitle系统调用)。我很确定argv [0]不适用于Solaris。
答案 3 :(得分:7)
查看setproctitle包
这是一个非常便携的版本,适用于许多平台。
答案 4 :(得分:4)
首先,我不确定C程序中的简单设置argv[0]
是否可以改变ps
中显示的名称。也许它在一些unixen中确实存在,但我的理解是它不会被期望。
其次,由于Windows特别是非POSIX兼容,因此在POSIX和非POSIX之间只有少数东西是“可移植的”。既然你专门说'ps',我会假设POSIX是你的优先考虑因素,而Windows可能无效。
更重要的是,我对更改argv[0]
的理解是,需要调用exec
才能进行这些更改。具体来说,exec
调用具有可执行文件的路径和单独的argv
列表。进行自己的调用允许您打破将可执行文件名放在argv[0]
。
您拥有OS library process management,可让您直接访问操作系统库以执行此操作。您应该考虑将脚本分为两部分 - 启动器和“实际工作”。启动器建立运行时环境并执行具有所需参数的实际工作。
在C中,您将自己的流程替换为另一个流程。在Python中,您将使用具有不同argv [0]的新Python解释器替换旧的Python解释器。希望它不会对此犹豫不决。有些程序检查argv [0]来决定他们在做什么。
您还可以使用subprocess.popen来设置所需的参数和可执行文件。然而,在这种情况下,父进程应该在孩子完成时继续收集孩子。父母可能不会做Popen.wait
答案 5 :(得分:3)
我对类似问题的回答标记为duplicate:
有更简单的(你不需要导入任何libs),但可能不那么优雅。你必须不要使用&#34; env&#34;在shebang线内。
换句话说,这将命名为&#34; python&#34;在进程列表中:
#!/usr/bin/env python
但是这将使用您的脚本名称命名:
#!/usr/bin/python
因此,您可以使用pidof -x scriptname
或ps -C scriptname
答案 6 :(得分:2)
我发现python-prctl在Linux下运行良好。你必须为Windows找到别的东西。
答案 7 :(得分: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 程序中,写入 argv[0]
只会更改 /proc/self/cmdline
中的参数和 /proc/self/comm
中的 not。因此,它不会影响 pidof
、top
COMMAND 列、ps
COMMAND 列、普通 pgrep
等。
setproctitle 包支持多个平台,并且 - 在 Linux 上 - 更改命令和参数向量。但是,它是一个 C 扩展。
答案 8 :(得分:-15)
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
请注意单个'='符号