python - Get pid of command ran by screen -
i'm developing minecraft (bukkit) server manager. it's porpuse start it, stop it, , check if running. last 1 causes problem. if pid of server:
subprocess.popen(["screen", "-dms", "minecraft-server", "serverstart.sh"])
i pid of screen command, not startup-script. seems pid 1 underneath pid of startup-script, suppose isn't relaiable. how can pid of java process?
edit: tried this, ps returns exit code 1 , no child pid. think because screen closes down imidiately.
check_output(['ps', '--ppid', str(popen(['screen', '-dms', 'test']).pid), '--no-headers', '-o', 'pid'])
if have process id of screen (the parent process, can access p.pid
assuming used p = subprocess.popen(...)
), can child process ids through like
ps --ppid <screen_pid> --no-headers -o pid
there's psutil.process(<screen_pid>).get_children()
available psutil module might preferred parsing output of ps since (i think) parses /proc
directly.
there functions inside python's standard os module allow stuff process ids directly, nothing child process ids of parent process id or process group id.
the following code:
#!/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) 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) cp in pp.get_children()] # generate 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 output print("screen pid: %d" % spid) cpids = get_child_pids(spid) print("child pids: %s" % cpids)
produces output:
./screen-pid.py creating screen session named: minecraft-server-k77d1 screen pid: 2274 child pids: [2276]
you can access child pid children pid list cpids[0]
.
the script spawns screen process specific name, finds parent process id , that, children process ids.
the random characters appended screen name there in case you're running multiple instances using same script. if you're not, can remove that, makes no difference leaving it.
the method of finding parent process id (parsing output of screen -ls
) isn't best, might alternatively iterate through processes using psutils.process_iter()
. seems work.
Comments
Post a Comment