13

I tried these two methods:

os.system("python test.py")

subprocess.Popen("python test.py", shell=True)

Both approaches need to wait until test.py finishes which blocks main process. I know "nohup" can do the job. Is there a Python way to launch test.py or any other shell scripts and leave it running in background?

Suppose test.py is like this:

for i in range(0, 1000000):
    print i

Both os.system() or subprocess.Popen() will block main program until 1000000 lines of output displayed. What I want is let test.py runs silently and display main program output only. Main program may quie while test.py is still running.

oHo
  • 41,098
  • 25
  • 141
  • 183
jack
  • 15,121
  • 32
  • 94
  • 122

2 Answers2

37

subprocess.Popen(["python", "test.py"]) should work.

Note that the job might still die when your main script exits. In this case, try subprocess.Popen(["nohup", "python", "test.py"])

Aaron Digulla
  • 297,790
  • 101
  • 558
  • 777
  • 1
    subprocess.Popen(["python", "test.py"]) just launches test.py and blocks main process by waiting for the output of test.py. – jack Oct 22 '09 at 07:30
  • 2
    That should only happen if you request `stdout=PIPE` as well. Which version of Python? Can you add a `print "xxx"` after the call to Popen to check that it really blocks? – Aaron Digulla Oct 22 '09 at 08:30
  • I just tested the code above and it works for me with Python 2.5.2 on Windows. Your problem must be something else. – Aaron Digulla Oct 22 '09 at 08:33
  • i tried again and it worked. sorry about the mistake and thanks for your answer. – jack Oct 22 '09 at 08:51
  • On Linux subprocess.Popen(["python", "test.py"]) blocks effectively the main process. – igor Nov 19 '15 at 15:49
  • @user3073745: It doesn't block on any platform. Processes are, by definition, independent of each other. They might block when you connect them with pipes. In that case, the writing side of the pipe can block when the reading side doesn't do it's job. – Aaron Digulla Nov 19 '15 at 16:58
  • @AaronDigulla, actually, according to my test subprocess.Popen(["python", "test.py"]) does nothing. If you want to execute test.py you have to add call to communicate function, and this is blocking : subprocess.Popen(["python", "test.py"]).communicate() – igor Nov 19 '15 at 17:13
  • @user3073745: `subprocess.Popen()` is always only the first call of a long block of code which manages the communication between the two processes. There is no "this will always work" answer in this case. – Aaron Digulla Nov 20 '15 at 10:00
  • 1
    @AaronDigulla: Is there no way to simply launch script in seperate process without blocking the main process ? – igor Nov 20 '15 at 10:07
  • There is are many way, just not a simple one. 1. You can redirect stdio of the child to /dev/null. 2. You can run it as a background process (so you're no longer the parent). 3. You can start threads to handle the IO while your main thread continues. – Aaron Digulla Nov 20 '15 at 10:51
  • @AaronDigulla - How to send the input parameters if the python scripts needs them. eg: If I execute this py file. `def start_listner(unique_id, keyword, limit): #do something` This `subprocess.Popen(["nohup", "python", "test.py"])` works but how can I pass unique_id, keyword and limit? – Marlon Abeykoon Dec 18 '15 at 11:28
  • @MarlonAbeykoon I can't answer that in a comment. Please ask a new question. – Aaron Digulla Jan 12 '16 at 14:05
1
os.spawnlp(os.P_NOWAIT, "path_to_test.py", "test.py")
Vissu
  • 318
  • 1
  • 2
  • 8