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

2025-03-20 08:47:00
admin
原创
46
摘要:问题描述:我可以更改 Python 脚本的有效进程名称吗?我想在获取系统进程列表时显示不同的名称而不是进程的真实名称。在 CI 中可以设置strcpy(argv[0],"othername"); 但是在 Python 中argv[0] = "othername" 似乎不...

问题描述:

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

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

但是在 Python 中

argv[0] = "othername"

似乎不起作用。当我获取进程列表时(ps ax在我的 Linux 机器中),真实名称没有改变。如果存在的话,我更喜欢可移植的解决方案(或者一个解决方案适用于 posix,另一个适用于 windows 环境)。


解决方案 1:

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

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

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

解决方案 2:

实际上在 Linux 上你需要两样东西:修改argv[0]C(forps auxf和朋友)并prctlPR_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将显示新的“testing yeah”进程名称:)。此外killallpkill将使用新名称。

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

更新:此答案中发布的解决方案有时在 FreeBSD 上无法很好地运行。我现在在各种 Linux 和 FreeBSD 机器上使用这个答案中所述的py-setproctitle已有一年左右了。到目前为止没有失败!每个人都应该这样做!:)。它使用的代码与PostgreSQL在其主数据库和子进程中使用的代码几乎相同。

解决方案 3:

查看setproctitle包

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

pip install setproctitle

 

import setproctitle

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

解决方案 4:

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

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

你是指服务名称吗?我猜是的,因为其他的都没有任何意义(至少对我这个不使用 Windows 的人来说)。

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

对于 Linux,我发现除了这个为您设置 argv[0] 的封装不良的模块之外,其他所有方法都不起作用。

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

解决方案 5:

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

有一种更简单(不需要导入任何库)但可能不太优雅的方法。您必须不要在 shebang 行中使用“env”。

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

#!/usr/bin/env python

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

#!/usr/bin/python

因此,您可以使用类似pidof -x scriptnameps -C scriptname

解决方案 6:

首先,我不确定简单地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 解释器。希望它不会因此而犹豫不决。有些程序会检查 argv[0] 来决定它们在做什么。

您还可以使用subprocess.popen来设置所需的参数和可执行文件。但是,在这种情况下,父进程应该在子进程完成后继续收集子进程。父进程可能只做一件事Popen.wait

解决方案 7:

我发现python-prctl在 Linux 下运行得很好。您必须为 Windows 寻找其他工具。

解决方案 8:

如果您只需要支持 Linux 并且只需要更改进程名称,那么您只需将其写入即可/proc/self/comm

例子:

#!/usr/bin/python3
import os
import subprocess

print(f'my pid: {os.getpid()}')

r = subprocess.run(['pidof', 'foo'], stdout=subprocess.PIPE, text=True)
print(f'pidof foo: {r}')
r = subprocess.check_output(['ps', 'p', str(os.getpid()), '-o', 'pid,comm,cmd'], text=True)
print(f'ps -p {os.getpid()} ...:
{r}')

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

r = subprocess.check_output(['pidof', '-w', 'foo'], text=True)
print(f'pidof -w foo: {r}')
r = subprocess.check_output(['pgrep', '^foo$'], text=True)
print(f"pgrep '^foo$': {r}")
r = subprocess.check_output(['ps', 'p', str(os.getpid()), '-o', 'pid,comm,cmd'], text=True)
print(f'ps -p ...:
{r}')

r = subprocess.run(['pidof', 'foo'], stdout=subprocess.PIPE, text=True)
print(f'pidof foo: {r}')

r = subprocess.run(['pidof', '-x', 'foo'], stdout=subprocess.PIPE, text=True)
print(f'pidof -x foo: {r}')

输出(在 Fedora 39 上):

$ python3 test.py argone argtwo
my pid: 528627
pidof foo: CompletedProcess(args=['pidof', 'foo'], returncode=1, stdout='')
ps -p 528627 ...:
    PID COMMAND         CMD
 528627 python3         python3 test.py argone argtwo

Setting comm to foo ...
pidof -w foo: 528627

pgrep '^foo$': 528627

ps -p ...:
    PID COMMAND         CMD
 528627 foo             python3 test.py argone argtwo

pidof foo: CompletedProcess(args=['pidof', 'foo'], returncode=1, stdout='')
pidof -x foo: CompletedProcess(args=['pidof', '-x', 'foo'], returncode=1, stdout='')

注意:在 Linux 上,在 C 程序中,写入argv[0]只会更改中的参数/proc/self/cmdline,而不会更改中的参数/proc/self/comm。因此,它不会影响topCOMMAND 列、psCOMMAND 列、纯文本pgrep等。


setproctitle包支持多种平台,在 Linux 上可更改命令和参数向量。不过,它是一个 C 扩展。

解决方案 9:

如果您想使用内置库,您也可以使用multiprocessing

import multiprocessing

if __name__ == '__main__':
    current_process = multiprocessing.current_process()
    current_process.name = 'NewProcessName'

    print(f"The process name is now: {current_process.name}")

解决方案 10:

Windows 上的一个超级技巧是复制 python.exe,将其重命名为 process_name.exe,然后使用重命名的 python 调用你的脚本。

这是一个超级黑客,但由于 Windows 上没有简单的解决方案,并且如果只需要快速完成一个脚本就可以监控它,那么这是一个公平的选择。

理论上它甚至可以编写脚本...超级黑客!?

解决方案 11:

In [1]: import sys

In [2]: print sys.argv[0]
C:Python25scriptsipython.py

In [3]: sys.argv[0] = 'foo'

In [4]: print sys.argv[0]
foo

注意单个“=”符号

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用