如果您有屏幕的进程 ID(父进程,p.pid
假设您使用过,您可以访问它p = Subprocess.Popen(...)
),您可以通过类似的方式获取子进程 ID
ps --ppid <SCREEN_PID> --no-headers -o pid
psutil模块也psutil.Process(<SCREEN_PID>).get_children()
提供了它,它可能比解析 ps 的输出更可取,因为(我认为)它直接解析。/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]
。
该脚本简单地生成具有特定名称的屏幕进程,然后找到父进程 ID 并从中找到子进程 ID。
如果您使用相同的脚本运行多个实例,则附加到屏幕名称的随机字符会出现。如果你不是,你可以删除所有这些,但离开它没有任何区别。
查找父进程 id(解析 的输出screen -ls
)的方法可能不是最好的,您也可以使用psutils.process_iter()
. 但这似乎有效。