Open another Python script from another Python process - python

I'm trying to open a python script from the main python program in a separate process.
For now let's just say that "main program" is a PyQt4 GUI program and "script" is the script (in a separate file) I am trying to run from my main program.
Why?
So the script keeps running after the main program is closed
So that when the script is ran my main program doesn't freeze while waiting for the script with an infinite loop to end.
I know that subprocess.Popen(), subprocess.call() and os.system() can open the file via the command line, but when they open a script with an infinite loop the main program hangs and crashes.
I also know that I could use QtCore.QCoreApplication.processEvents() to keep the main program running, but this does not work in my case.
So I figured the best solution to keep the script and the Main Program correctly running is the have separate processes.
How would I open script.py file in a separate process or in a way that would not freeze up my program.

Calling an external command in Python is probably what you're looking for. The author perfectly describes how to launch different python script that keeps running when your main program is closed.

Don't run python scripts as subprocesses, import the corresponding modules and call the desired functions instead. If you need to run Python code in a separate process, you could use multiprocessing:
multiprocessing.Process(target=infinite_loop, args=['arg 1', 2]).start()
Related: Call python script with input with in a python script using subprocess.
To avoid "freezing" your GUI, do not call functions that block for long in your GUI thread. Either use threads or async. API (here's tkinter code example that uses createfilehandler() and .after() calls, to read output from a subprocess without blocking the GUI).
Popen() only starts a child process and it does not wait for it to exit. If Popen() "freezes" your program something else is broken. Here's code example that starts/stops a tkinter progressbar on start/end of a subprocess.
Qt has its own API: QThread, QProcess, signals that you could use to run a subprocess. Related: How to do stuff during and after a child process.

Related

How can I start a GUI program from Python, but have the process end when the user closes the window?

I want to write a Python script which will start a GUI program (as in, run a binary program with subprocess.run or os.system or something). The script should not block until the program is done, it should start it and then keep running.
I'm doing this on Ubuntu.
I tried subprocess.Popen, but if I run, say subprocess.Popen("gedit"), I get strange behavior. If I open the Ubuntu system monitor (process manager), I can see that the gedit process appears when I run the script, and the gedit window itself opens. But if I close the window, the process doesn't end in the system monitor. The process stays there until my python script exits.
How can I get the behavior I want? The only thing I can think of right now is to just call subprocess.run in a different Python thread, is that the only thing I can do?
Try using subprocess.call. This has worked for me before.
subprocess.call(['command', 'arguments'])
The program should end when the window is closed.
You have to kill the subprocess you've created before you exit the program.
Try this.

Run python script from python script BUT outside of python script

It sounds like riddle or joke but actually I havent found answer to this problem.
What is actually the problem?
I want to run 2 scripts. In first script I call another script but I want them to continue parallely and not in 2 separate threads. Mainly I dont want 2nd script to be running inside 1st python script(That means if I run Chrome Browser from python script and then shut down the python script, the Chrome will be shut down too).
What I want is like on Linux machine: I open two terminals and run both scripts in each terminal - They are not two threads, they are independent on each other, shutting one will NOT shut down the other. Or it can be like on Linux machine where I can run 2 python scripts in terminal behind background with 'python xxx.py &' (&) symbol.
Summary:
I would like to run inside 'FIRST.py' script 'SECOND.py' script. However not with threading module and mainly have SECOND.py script independent on FIRST.py script, that is, shutting down FIRST.py will not have any consequence on SECOND.py.
THE SOLUTION SHOULD BE WORKING ON WINDOWS, LINUX AND MAC.
BTW:
I tried on windows:
subprocess.call(['python','second.py','&'])
subprocess.call(['python','second.py'])
os.system('python second.py') # I was desperate
They run serially, so first.py script is blocked untill second.py finishes.
I havent try Threading with daemon=False but I feel its kind of Demon and I dont feel my skill is that far that I can control threads existing outside of my playground :)
Thanks in advance for help
You can use the Popen constructor from the subprocess module to launch background processes, using
import subprocess
p = subprocess.Popen(["python","second.py"])
creates a background process and execution of first.py is not blocked.

Using os.system() in Python is open a program, can't see window of launched program

I am trying to launch a program/GUI from within a python code.
From the terminal, I can get the program to launch by simply typing the program name. A few lines get outputted to the terminal, and then a separate window opens with the GUI.
I tried to emulate this in python by running
os.system("<program name>")
The typical output lines, as mentioned above, get printed to the console, but no window opens up with the GUI.
Can os.system() be used to execute programs that have their own separate window?
From the Python manual:
[os.system] is implemented by calling the Standard C function
system()
That being said, you shouldn't have any problems launching a GUI application with os.system. I've just tried it myself and it works fine.
It also mentions in the manual that:
The subprocess module provides more powerful facilities for spawning
new processes and retrieving their results; using that module is
preferable to using this function.
Maybe that's worth a try. Do any other GUI applications work when you spawn them with os.system?
Here is a solution using subprocess
import subprocess
subprocess.Popen("notepad.exe")
Or if you want to run a python program with a specific interpreter:
subprocess.Popen('{0} {1}'.format(PythonInterpreterPath,PythonFilePath.py))

Python subprocess running out of order on Windows

I'm running a python script on Windows.
I have a python script like this:
subprocess.call(1)
subprocess.Popen(2)
subprocess.call(3)
when I run the script, the results I get runs like this:
subprocess.call(3)
subprocess.call(1)
subprocess.Popen(2)
Why is this happening?
Each new process you create with subprocess spawns a new sub-process, hence its name. This means the commands will finish running at different times meaning you get the results in a different order.
It is not the same as calling a function in Python, where the function finishes running before the others are ran.

Python script embedded in shell script, does not exit and daemon solution does not fit the needs

This question extends/revives this one.
The relevance to revive this topic is due to the failure in solving the same problem with the given answers.
The bash script executes a python script embedded. Something like
#!/bin/bash
./pyscript.py
chmod +x pyscript.py permission was given.
Alternative ways to run the script were used.
(python -u pyscript.py or /usr/bin/python pyscript.py)
As the title states the python program does not exit.
I have tried the following attempts within the python script to solve the issue:
sys.exit(0); %the program catches the correct exception
os._exit(1) %does not work and the correct exception is catched
sys.stdout.flush() %to clean the buffer of the stdout
The daemon solution is not suitable for what I need, because running in the background independently from the main script will not wait for the execution of the python program untill the end.
What are the alternative solutions that remain for this case?
Have you tried to use strace -p $PID on the python process? The output will not always be useful however.
From the code perspective, in addition to threads I would check if there are any signal handlers (which maybe do not terminate for some reason).
As far as threads are concerned, you might be interested in this, although I believe someone mentioned it in the other thread.
Finnally the problem is solved.
The program in python wich I've been trying to kill the process runs with multiple threads.
sys.exit(0) only terminates the thread in which the program is called.
The os._exit(1) was called with the sys.exit(0) before its execution (fail!).
By running os._exit(1) without sys.exit(0) before, the program exit the python script.
The reason must be that sys.exit() only terminates the thread in which it is called and allows the program to clean resources, while os._exit() does an abrupt program termination.
Found here.
With this solution it's better guarantee the termination of any task the program should end and then call os._exit.
what I usually do to separate a script from the main shell terminal process is sending the script inside a screen session detached. Then I kill the pid of the script without any trouble.
But for this particular case I want the program waiting for the end of the python subscript and not as a parallel process.
Also, you might want to try the trace module, i.e. running your program with #!/usr/bin/env python -m trace --trace. If python is executing some of your code (which it probably is), it should show you details on that.

Categories