-->

How to get the script path of a python process who

2019-05-21 04:56发布

问题:

I'm trying to get and kill all other running python instances of the same script, I found an edge case where the path is not in psutil's cmdline list, when the process is started with ./myscript.py and not python ./myscript.py

the script's content is, note the shebang:

#!/bin/python
import os
import psutil
import sys
import time

for proc in psutil.process_iter():
    if "python" in proc.name():
        print("name", proc.name())
        script_path = sys.argv[0]
        proc_script_path = sys.argv[0]
        if len(proc.cmdline()) > 1:
            proc_script_path = proc.cmdline()[1]
        else: 
            print("there's no path in cmdline")
        if script_path.startswith("." + os.sep) or script_path.startswith(".." + os.sep):
            script_path = os.path.normpath(os.path.join(os.getcwd(), script_path))
        if proc_script_path.startswith("." + os.sep) or proc_script_path.startswith(".." + os.sep):
            proc_script_path = os.path.normpath(os.path.join(proc.cwd(), proc_script_path))
        print("script_path", script_path)
        print("proc_script_path", proc_script_path)
        print("my pid", os.getpid())
        print("other pid", proc.pid)
        if  script_path == proc_script_path and os.getpid() != proc.pid:
            print("terminating instance ", proc.pid)
            proc.kill()

time.sleep(300)

how can I get the script path of a python process when it's not in psutil's cmdline?

回答1:

When invoking a python script like this, the check if 'python' in proc.name() is the problem. This will not show python or python3 for the scripts in question, but it will show the script name. Try the following:

import psutil

for proc in proc.process_iter():
    print('Script name: {}, cmdline: {}'.format(proc.name(), proc.cmdline()))

You should see something like (): Script name: myscript.py, cmdline: ['/usr/bin/python3', './myscript.py']

Hope this helps.



回答2:

when the process is started with ./relative/or/absolute/path/to/script.py and not python /relative/or/absolute/path/to/script.py the psutil.Process.name() is script.py and not python.



回答3:

To get the list of process paths running your script.py:

    ps -eo pid,args|awk '/script.py/ && $2 != "awk" {print}'

To get get the list of process paths running your script.py not having psutil in the path. Replace your script.py and psutil in the following script.

    ps -eo pid,args|awk '! /psutil/ && /script.py/ && $2 != "awk" {print}'

explanation:

ps -eo pid,args list all processes, providing process id and process path (args)

! /psutil/ match all process paths not having psutil in the path.

&& /script.py/ and match all process paths having script.py in the path.

&& $2 != "awk" and not wanting this awk process.

{print} output the matched lines.