0

How can i check if a specific python file is running through another python file? for example in python file1 there will be a condition:

if file.IsRunning:

i have tried to do:

__author__ = 'Cyber-01'
import psutil

def IsRunning(name):
    for pid in psutil.pids():
        try:
            p = psutil.Process(pid)
            if len(p.cmdline())>1:
                if name in p.cmdline()[1]:
                    return True
        except:
            None
    return False

if running("server.py"):
    print "yes"

but it always returns yes no matter

4
  • To clarify your question: By 'throw'. do you mean 'via'? Commented Mar 24, 2017 at 21:45
  • 2
    I think they meant "through" Commented Mar 24, 2017 at 21:48
  • 1
    This seems to work for me. Although I would recommend replacing the None line with pass. Is it possible there is a zombie server.py process? Commented Mar 24, 2017 at 21:56
  • how can i identify a zombie process? Commented Mar 25, 2017 at 17:13

2 Answers 2

4

First-attempt:

import psutil

def running(name):
    name_list = []
    for proc in psutil.process_iter():
        try:
            pinfo = proc.as_dict(attrs=['pid', 'name'])
            if name in pinfo['name']:
                return True
            else:
                pass
        except:
            return False

EDIT

A solution more in line with the OP's original post:

def running3(program, scriptname):
    for pid in psutil.pids(): # Iterates over all process-ID's found by psutil,  
        try:
            p = psutil.Process(pid) # Requests the process information corresponding to each process-ID, the output wil look (for example) like this: <psutil.Process(pid=5269, name='Python') at 4320652312>
            if program in p.name(): # checks if the value of the program-variable that was used to call the function matches the name field of the plutil.Process(pid) output (see one line above). So it basically calls <psutil.Process(pid=5269, name='Python') at 4320652312>.name() which is --> 'Python'
                """Check the output of p.name() on your system. For some systems it might print just the program (e.g. Safari or Python) on others it might also print the extensions (e.g. Safari.app or Python.py)."""
                for arg in p.cmdline(): # p.cmdline() echo's the exact command line via which p was called. So it resembles <psutil.Process(pid=5269, name='Python') at 4320652312>.cmdline() which results in (for example): ['/Library/Frameworks/Python.framework/Versions/3.4/Resources/Python.app/Contents/MacOS/Python', 'Start.py'], it then iterates over is splitting the arguments. So in the example you will get 2 results: 1 = '/Library/Frameworks/Python.framework/Versions/3.4/Resources/Python.app/Contents/MacOS/Python' and 2 = 'Start.py'. It will check if the given script name is in any of these.. if so, the function will return True.
                    if scriptname in str(arg):  
                        return True
                    else:
                        pass
            else:
                pass
        except:
            continue

if running3('Python', 'server.py'):
    print("Yes, the specified script is running!")
else:
    print("Nope, can't find the damn process..")

As to why the OP's code wasn't working:

I can see a couple of wrongs in the code. First of all, the indentation of return False places it outside the for-loop, thereby creating a situation in which the function will always return False.

Furthermore the psutil.Process.cmdline() returns the command that was used to execute the current process. When psutil.Process.cmdline(1) is called it is supposed to return the command line via which the process of PID 1 was called. However, this seems to throw up a lot of permission errors. This, in turn, causes if len(p.cmdline())>1 to fail almost all of the time, raising the exception and thus returning None in the OP's code.

Second EDIT (tested the two solutions for optimal performance)

  • Code 1 (using psutil.process_iter()): 100 loops, best of 3: 4.37 msec per loop
  • Code 2 (using psutil.Process(pid).name()): 1000 loops, best of 3: 945 usec per loop
  • Conclusion: the 2nd code seems to be your best bet!
Sign up to request clarification or add additional context in comments.

30 Comments

In the OP code, they are searching for the second item on the command line (the first parameter). name from the process doesn't contain that information.
Well, might be a good thing depending on what you want.. My option leaves less space for confusion. Since if you have a process like /somefolder/Safari/some_related_but_independent_sub_process and you are checking if Safari is running, the OP's code will answer yes, while mine will answer no. It all depends on what you want.. How specific you want to get.
why isn't it good for a large scale project and what was wrong with my code?
i want to be able to find the process-c:\server.py
Because creating a list and appending each item is quite memory intensive (if you are talking really large scale, that will slow you down). Having another look at your code though.. I think your indentation on return False might be faulty, since your function will always return False..
|
1

A simple way to do this is:

import psutil
print("Roblox" in (i.name() for i in psutil.process_iter()))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.