有没有办法在Python中更改有效的进程名称?
我可以更改Python脚本的有效进程名称吗? 当我得到系统进程列表时,我想显示一个不同的名称,而不是进程的真实名称。 在CI可以设置
strcpy(argv[0],"othername");
但在Python中
argv[0] = "othername"
似乎没有工作。 当我得到进程列表(与我的Linux机箱中的ps ax
)真实姓名不会改变。 如果存在的话,我更喜欢一个便携式解决scheme(或者一个解决scheme用于posix,另一个解决scheme用于windows环境)。
提前致谢
简而言之,没有便携的方法。 您必须testing系统并使用该系统的首选方法。
此外,我对Windows上进程名称的含义感到困惑。
你的意思是服务名称? 我认为是这样,因为没有别的东西真的有意义(至less对于我的非Windows使用大脑)。
如果是这样的话,你需要使用Tim Golden的WMI接口,并在服务上调用.Change方法…至less根据他的教程 。
对于Linux,除了为你设置argv [0]的这个打包不足的模块外,没有任何方法可以工作。
我甚至不知道这是否适用于BSD变体(它具有setproctitle系统调用)。 我很确定argv [0]在Solaris上不起作用。
我最近编写了一个Python模块,以便携方式更改进程标题: https : //github.com/dvarrazzo/py-setproctitle
它是PostgreSQL用于执行标题更改的代码的一个包装。 它目前正在针对Linux和Mac OS X进行testing:Windows(function有限)和BSD移植正在进行中。
编辑:截至2010年7月,该模块在BSD上工作,在Windows上有限的function,并已移植到Python 3.x。
实际上你需要在Linux上做两件事:从C
(对于ps auxf
和朋友)修改argv[0]
,并用PR_SET_NAME
标志调用prctl
。
从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
会显示新的'testing yeah'进程名:)。 另外killall
和pkill
将使用新名称。
顺便说一句,从googlecode的procname也改变了argv[0]
,因此,甚至改变ps auxf
输出。
更新 :在这个答案中发布的解决scheme有时不会在FreeBSD上播放。 我现在使用py-setproctitle 在这个答案中陈述了一年左右的各种linux和freebsd框。 没有失败迄今! 大家也应该! :)。 它使用与PostgreSQL在其主数据库和subprocess中使用的几乎相同的代码。
首先,我不确定在C程序中简单地设置argv[0]
改变ps
显示的名称。 也许它在一些unixen,但我的理解是,这是不能预料的。
其次,由于Windows特别不符合POSIX标准,在POSIX和非POSIX之间只有几件事是“可移植的”。 既然你专门说'ps',我会假定POSIX是你的优先级,而Windows可能无法工作。
更重要的是,我对改变argv[0]
理解是,它需要调用exec
来进行这些更改。 具体来说, exec
调用既有一个可执行文件的path,也有一个单独的argv
列表。 制作自己的调用允许您打破将可执行文件名称放在argv[0]
的shell约定。
您有OS库进程pipe理 ,可以让您直接访问OS库来执行此操作。 你应该考虑把你的剧本分成两部分 – 一个先发和“真正的作品”。 启动器build立运行时环境,并用所需的参数build立exec的实际工作。
在C中,你正在用另一个replace你自己的进程。 在Python中,你正在用一个不同的argv [0]替代旧的Python解释器。 希望它不会妨碍这一点。 一些程序检查argv [0]来决定他们在做什么。
您还可以使用subprocess.popen来设置所需的参数和可执行文件。 然而,在这种情况下,当孩子结束时,父母的过程应该在周围收集孩子。 父母可能不会做任何比Popen.wait
更多的Popen.wait
看看setproctitle包
这是一个相当便携的版本,可以在很多平台上运行。
我对类似问题的回答标为重复 :
有简单的(你不需要导入任何库),但也许不是那么优雅的方式。 你必须不使用shebang行内的“env”。
换句话说,这将在进程列表中被命名为“python”:
#!/usr/bin/env python
但是这将以你的脚本名来命名:
#!/usr/bin/python
所以你可以用pidof -x scriptname
或ps -C scriptname
来find它
我发现python-prctl在Linux下工作得很好。 你将不得不为Windowsfind其他的东西。
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
请注意单个“=”号