web-dev-qa-db-ja.com

Pythonで有効なプロセス名を変更する方法はありますか?

Pythonスクリプトの有効なプロセス名を変更できますか?システムプロセスリストを取得するときに、プロセスの実際の名前の代わりに別の名前を表示したいです。Cでは設定できます。

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

しかし、Python

argv[0] = "othername"

動作しないようです。プロセスリストを取得するとき(ps ax私のLinuxボックスでは)本名は変わりません。ポータブルソリューション(またはPOSIX用とWindows環境用の別のソリューション)があれば、それが好きです。

前もって感謝します

72
Emilio

簡単に言えば、ポータブルな方法はありません。システムをテストし、そのシステムに適した方法を使用する必要があります。

さらに、Windowsのプロセス名が何を意味するのか混乱しています。

サービス名を意味しますか?私がそう思うのは、(少なくともWindowsを使用していない脳にとっては)他に何も意味がないからです。

その場合は、 Tim GoldenのWMIインターフェイス を使用し、少なくとも tutorial に従ってサービスの.Changeメソッドを呼び出す必要があります。

Linuxの場合、argv [0]を設定する このパッケージ化が不十分なモジュール を除いて、私が見つけたどのメソッドも機能しませんでした。

これがBSDバリアント(setproctitleシステムコールがある)で機能するかどうかさえ知りません。 argv [0]はSolarisでは動作しないと確信しています。

13
Van Gale

最近、ポータブルな方法でプロセスタイトルを変更するPythonモジュールを作成しました。チェック https://github.com/dvarrazzo/py-setproctitle

これは、タイトルの変更を実行するためにPostgreSQLが使用するコードのラッパーです。現在、LinuxおよびMac OS Xに対してテストされています。Windows(機能が制限されています)およびBSDの移植が進行中です。

Edit:2010年7月現在、このモジュールはBSDで動作し、Windowsで機能が制限されており、Python 3に移植されています。 。バツ。

81
piro

実際には、Linuxで2つのことが必要です:argv[0]Cから(ps auxfおよび友人用に)変更し、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」と表示されます:(ただし、topps -Aは新しい「testing yeah」プロセス名を表示します:)。また、killallおよびpkillも新しい名前で機能します。

ところで、googlecodeからのprocnameもargv[0]を変更します。したがって、ps auxf出力も変更します。

[〜#〜] update [〜#〜]:この回答に掲載されている解決策は、FreeBSDでは時々Niceを再生しません。私は今、さまざまなLinuxおよびfreebsdボックスで1年ほどの間 py-setproctitle 述べられている この回答で を使用しています。今のところ失敗はありません!みんなもそうすべきです! :)。メインデータベースと子プロセスで PostgreSQLses とほぼ同じコードを使用します。

51
Vadim Fint

setproctitle packageをご覧ください

これは非常にポータブルなバージョンであり、多くのプラットフォームで動作します。

7
valgog

まず、Cプログラムでargv[0]を設定するだけで、psに表示される名前が移植可能に変更されるかどうかわかりません。おそらくunixenでそれを行うかもしれませんが、私の理解ではそれは期待されていません。

第二に、Windowsは特にPOSIXに準拠していないため、POSIXと非POSIXの間で「移植可能」なものはごくわずかです。特に「ps」と言うので、POSIXが優先事項であり、Windowsが機能しない可能性があると想定します。

さらに重要なことは、argv[0]の変更に関する私の理解では、これらの変更を行うにはexecの呼び出しが必要だということです。具体的には、exec呼び出しには、実行可能ファイルへのパスと個別のargvリストの両方があります。独自の呼び出しを行うと、argv[0]に実行可能ファイル名を入れるというシェルの規則を破ることができます。

OSライブラリプロセス管理 があり、これを行うためにOSライブラリに直接アクセスできます。スクリプトを2つの部分に分けることを検討する必要があります。スターターと「実際の作業」です。スターターはランタイム環境を確立し、目的のパラメーターを使用して実際の作業を実行します。

Cでは、独自のプロセスを別のプロセスに置き換えています。 Pythonでは、古いPythonインタープリターを別のargv [0]を持つ新しいインタープリターに置き換えています。うまくいけば、これは問題になりません。一部のプログラムはargv [0]をチェックします。彼らが何をしているかを決めるために。

また、 subprocess.popen を使用して、目的の引数と実行可能ファイルを設定できます。ただし、この場合、親プロセスは、子が終了したときに子を収集するために残ります。親はPopen.wait以外のことをしていない可能性があります

4
S.Lott

duplicate とマークされた同様の質問に対する私の答え:

シンプルなものもあります(ライブラリをインポートする必要はありません)が、それほどエレガントな方法ではないかもしれません。 Shebangライン内で「env」を使用しないでください。

言い換えれば、これはプロセスリストで「python」と命名されます:

#!/usr/bin/env python

ただし、これはスクリプト名で名前が付けられます。

#!/usr/bin/python

したがって、pidof -x scriptnameps -C scriptnameのようなもので見つけることができます。

3
Sasha Ru

Linuxで python-prctl が非常にうまく機能することがわかりました。 Windows用に何か他のものを見つける必要があります。

2
Vukasin Toroman