2

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?

Wis
  • 484
  • 7
  • 22

3 Answers3

2

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.

g_uint
  • 1,903
  • 3
  • 17
  • 30
  • I don't think you understood the question. I want to get the script path from a psutil process instance. – Wis Apr 07 '19 at 09:04
  • 1
    you're right, just found that out, and wrote and posted an answer at the same time as you edited yours. – Wis Apr 07 '19 at 10:30
1

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.

Wis
  • 484
  • 7
  • 22
0

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.

Dudi Boy
  • 4,551
  • 1
  • 15
  • 30
  • I rejected your question edit which added awk tag and removed the shebang tag because this question is more about python and psutil (and not shell script), a _cross-platform_ library for process and system monitoring, the ps and awk commands are unix-specific. the shebang tag is relevant because without it you can't run a script only with it's path. – Wis Apr 09 '19 at 00:14