To launch a program in a non blocking way but still being able to see the output of program, the program has to be launched in a separate thread or process. Ryan has posted a nice code sample here: Python Subprocess.Popen from a thread
Keep in mind that the last line print myclass.stdout will print the output how it appears at that time. If program is just being launched, it might not have output anything at all, so your code should probably read from myclass.stdout until it receives the line you need.
To launch a program in a non blocking way but still being able to see the output of program, the program has to be launched in a separate thread or process. Ryan has posted a nice code sample here: Python Subprocess.Popen from a thread
Keep in mind that the last line print myclass.stdout will print the output how it appears at that time. If program is just being launched, it might not have output anything at all, so your code should probably read from myclass.stdout until it receives the line you need.
You can run it in a thread (so that it doesn't block your code from running), and get the output until you get the second line, then wait for it to terminate. This is an example that will read the output from the command dir /s on Windows to get all the directory listing.
import subprocess, thread, time
def run():
global can_break
args = ["dir", "/s"]
shell = True
count = 0
popen = subprocess.Popen(args, shell=shell, stdout=subprocess.PIPE)
while True:
line = popen.stdout.readline()
if line == "": continue
count += 1
if count == 2:
do_something_with(line)
break
print "We got our line, we are waiting now"
popen.wait()
print "Done."
can_break = True
def do_something_with(line):
print '>>> This is it:', line
thread.start_new_thread(run, tuple())
can_break = False
while not can_break:
print 'Wait'
time.sleep(1)
print 'Okay!'
Output will look like:
Wait >>> This is it: Volume Serial Number is XXXX-XXXX We got our line, we are waiting now Wait Wait Wait . . . Done. Wait Okay!
Videos
I am wondering if this can be achieved with subprocess. Run the process and write output
I have two files:
main.py:
import subprocess
import shlex
def main():
command = 'python test_output.py'
logfile = open('output', 'w')
proc = subprocess.Popen(shlex.split(command), stdout=logfile)
if __name__ == "__main__":
main()and test_output.py:
from time import sleep
import os
for i in range(0, 30):
print("Slept for => ", i+1, "s")
sleep(1)
os.system("notify-send completed -t 1500")The output of the process is written to logfile once the child process is completed. Is there any way to:
Start child process from main and exit it (like it does now).
Keep running the child process in background.
As child process produces an output, write it immediately to logfile. (Don't wait for the child process to finish, as it does now.)
Or write to Named Pipes alternatively but don't keep it waiting to read (non-blocking)
Is it possible to do everything in background, without keeping main.py waiting?
Im using pyautogui to automate something when it clicks on the program its supposed to automate it stops nd only runs when my python intrepter is the current tab
Use the shebang line in your python script. Make it executable using the command,
chmod +x test.py
Use no hangup to run the program in the background even if you close your terminal,
nohup /path/to/test.py &
or simply (without making any change in your program)
nohup python /path/to/test.py &
Do not forget to use & to put it in the background.
Role of nohup: nohup makes your script ignore SIGHUP, and redirects stdout/stderr to a file nohup.out, so that the command can continue running in the background after you log out. If you close the shell/terminal or log off, your command is no longer a child of that shell. It belongs to init process. If you search in pstree you'll see it is now owned by process 1 (init).
To see the process again, use in terminal,
ps ax | grep test.py
That cannot be brought back to the foreground because the foreground (as the terminal already closed) no longer exists. So there is no way to get that terminal back again once it is closed.
python test.py &
will run the file in the background.
In order to find the running program, you can use ps -e to list all running programs. You can use grep to find your particular program from the list.
& is a shell feature. If you want it to work with subprocess, you must specify shell=True like:
subprocess.call(command, shell=True)
This will allow you to run command in background.
Notes:
Since
shell=True, the above usescommand, notcommand_list.Using
shell=Trueenables all of the shell's features. Don't do this unlesscommandincludingthingycomes from sources that you trust.
Safer Alternative
This alternative still lets you run the command in background but is safe because it uses the default shell=False:
p = subprocess.Popen(command_list)
After this statement is executed, the command will run in background. If you want to be sure that it has completed, run p.wait().
If you want to execute it in Background I recommend you to use nohup output that would normally go to the terminal goes to a file called nohup.out
import subprocess
subprocess.Popen("nohup usr/local/bin/otherscript.pl {0} >/dev/null 2>&1 &", shell=True)
>/dev/null 2>&1 & will not create output and will redirect to background
I made this python script that gives a windows notification if your capslock is on or off. The script works but the problem is, whenever I close VSCODE it stops from working. Care to share any tips folks?
Assumptions: you are running Rasbian
You have a couple different options. For testing, you can run nohup ./python_script.py &. That uses a program called nohup to redirect all console output to a file, and then give you back your terminal.
Long term, you will probably want to start the program with cron and run it on reboot, so if the power goes out out your program will start as soon as it boots back up.
Cron is a little more advanced and requires a little more thought to setup. You have options as far as running a program at a certain time. For your application, it sounds like you can do something as simple as
$ crontab -e
and add the line:
@reboot /home/vivek/bin/python_script.py
Save and close, and then run
# update-rc.d cron defaults
A quite messy way of doing this is to first start the .py in the command line before starting LXDE, then use Ctrl-Z. Type "bg && startx". The .py will run in the command line while LXDE can be used.
Credit to Gerben for the "Ctrl-Z" and "bg" idea.
While jkp's solution works, the newer way of doing things (and the way the documentation recommends) is to use the subprocess module. For simple commands its equivalent, but it offers more options if you want to do something complicated.
Example for your case:
import subprocess
subprocess.Popen(["rm","-r","some.file"])
This will run rm -r some.file in the background. Note that calling .communicate() on the object returned from Popen will block until it completes, so don't do that if you want it to run in the background:
import subprocess
ls_output=subprocess.Popen(["sleep", "30"])
ls_output.communicate() # Will block for 30 seconds
See the documentation here.
Also, a point of clarification: "Background" as you use it here is purely a shell concept; technically, what you mean is that you want to spawn a process without blocking while you wait for it to complete. However, I've used "background" here to refer to shell-background-like behavior.
Note: This answer is less current than it was when posted in 2009. Using the subprocess module shown in other answers is now recommended in the docs
(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.)
If you want your process to start in the background you can either use system() and call it in the same way your shell script did, or you can spawn it:
import os
os.spawnl(os.P_DETACH, 'some_long_running_command')
(or, alternatively, you may try the less portable os.P_NOWAIT flag).
See the documentation here.