p.pid
画面のプロセス ID (を使用したと仮定してアクセスできる親プロセス) がある場合はp = Subprocess.Popen(...)
、次のような方法で子プロセス ID を取得できます。
ps --ppid <SCREEN_PID> --no-headers -o pid
(私が思うに)直接解析するため、psの出力を解析するよりも好ましいかもしれないpsutilモジュールからもpsutil.Process(<SCREEN_PID>).get_children()
利用できます。/proc
Python の標準 os モジュール内には、プロセス ID を直接処理できる関数もいくつかありますが、親プロセス ID またはプロセス グループ ID の子プロセス ID を取得する関数はありません。
次のコード:
#!/bin/env python
import subprocess, random, string, re
import psutil
SERVER_SCRIPT = "./serverstart.sh"
def get_random_key(strlen):
return 'K'+''.join(random.choice(string.hexdigits) for x in range(strlen-1))
def find_screen_pid(name):
ph = subprocess.Popen(["screen", "-ls"], stdout=subprocess.PIPE)
(stdout,stderr) = ph.communicate()
matches = re.search(r'(\d+).%s' % name, stdout, re.MULTILINE)
if(matches):
pids = matches.groups()
if(len(pids) == 1): return int(pids[0])
else: raise Exception("Multiple matching PIDs found: %s" % pids)
raise Exception("No matching PIDs found")
def get_child_pids(parent_pid):
pp = psutil.Process(parent_pid)
return [ int(cp.pid) for cp in pp.get_children()]
# Generate a random screen name, in case you're running multiple server instances
screenname = "minecraft-server-" + get_random_key(5)
print("Creating screen session named: %s" % screenname)
subprocess.Popen(["screen", "-dmS", screenname, SERVER_SCRIPT]).wait()
spid = find_screen_pid(screenname) # Display some output
print("Screen PID: %d" % spid)
cpids = get_child_pids(spid)
print("Child PIDs: %s" % cpids)
出力を生成します。
./screen-pid.py
次の名前の画面セッションを作成しています: minecraft-server-K77d1
画面 PID: 2274
子 PID: [2276]
を使用して、子 pid リストから子 pid にアクセスできますcpids[0]
。
このスクリプトは、特定の名前で screen プロセスを生成し、親プロセス ID を見つけ、そこから子プロセス ID を見つけます。
同じスクリプトを使用して複数のインスタンスを実行している場合に備えて、スクリーン名にランダムな文字が追加されています。そうでない場合は、それをすべて削除できますが、そのままにしておくことに違いはありません。
親プロセス ID を見つける方法 ( の出力を解析するscreen -ls
) はおそらく最善ではありませんpsutils.process_iter()
。しかし、これはうまくいくようです。