How to determine pid of process started via os.system

27,992

Solution 1

os.system return exit code. It does not provide pid of the child process.

Use subprocess module.

import subprocess
import time
argument = '...'
proc = subprocess.Popen(['python', 'bar.py', argument], shell=True)
time.sleep(3) # <-- There's no time.wait, but time.sleep.
pid = proc.pid # <--- access `pid` attribute to get the pid of the child process.

To terminate the process, you can use terminate method or kill. (No need to use external kill program)

proc.terminate()

Solution 2

Sharing my solution in case it can help others:

I took the info from this page to run a fortran exe in the background. I tried to use os.forkpty to get the pid of it, but it didnt give the pid of my process. I cant use subprocess, because I didnt find out how it would let me run my process on the background.

With help of a colleague I found this:

exec_cmd = 'nohup ./FPEXE & echo $! > /tmp/pid'

os.system(exec_cmd)

In case of wanting to append pids to the same file, use double arrow.

Solution 3

You could use os.forkpty() instead, which, as result code, gives you the pid and fd for the pseudo terminal. More documentation here: http://docs.python.org/2/library/os.html#os.forkpty

Share:
27,992
Sebastian Werk
Author by

Sebastian Werk

Filled to get the badge d;

Updated on November 14, 2020

Comments

  • Sebastian Werk
    Sebastian Werk over 3 years

    I want to start several subprocesses with a programm, i.e. a module foo.py starts several instances of bar.py.

    Since I sometimes have to terminate the process manually, I need the process id to perform a kill command.

    Even though the whole setup is pretty “dirty”, is there a good pythonic way to obtain a process’ pid, if the process is started via os.system?

    foo.py:

    import os
    import time
    os.system("python bar.py \"{0}\ &".format(str(argument)))
    time.sleep(3)
    pid = ???
    os.system("kill -9 {0}".format(pid))
    

    bar.py:

    import time
    print("bla")
    time.sleep(10) % within this time, the process should be killed
    print("blubb")
    
  • Sebastian Werk
    Sebastian Werk over 10 years
    Thanks, I will use this as a fallback, if os.spawnl(...) fails
  • falsetru
    falsetru over 10 years
    @SebastianWerk, According to os.spawn* documentation, "Note that the subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using these functions. ..."
  • Sebastian Werk
    Sebastian Werk over 10 years
    I know, therefor I used it in first place, but it takes around 20ms to start one process on my computer, and this is a bit too long ):
  • falsetru
    falsetru over 10 years
    @SebastianWerk, How about posting EDIT part of your question as answer and accepting it instead of trying to close your question?
  • Tommy
    Tommy almost 8 years
    does this work if you want the main process (the code above) to go down after spawning the new one and writing a pid file?
  • sai harsha vardhan
    sai harsha vardhan about 2 years
    how to capture the stdout to a file if we use this approach? nohup ./FPEXE | tee my_log.log & echo $! > /tmp/pid . Becuase the pid capture is the proccess id of tee and not the pid of the actual command.