Bring the current Python program to background
Update: To properly daemonize your process, use daemonize.
Original answer: Since the shell is waiting for your process to finish, the main process must terminate. You can use os.fork()
to fork off a child process and sys.exit()
from the parent process:
import os
import sys
if os.fork():
sys.exit()
# Child code goes here
How to constantly run Python script in the background on Windows?
On Windows, you can use pythonw.exe
in order to run a python script as a background process:
Python scripts (files with the extension
.py
) will be executed bypython.exe
by default. This executable opens a terminal, which stays
open even if the program uses a GUI. If you do not want this to
happen, use the extension.pyw
which will cause the script to be
executed bypythonw.exe
by default (both executables are located in
the top-level of your Python installation directory). This suppresses
the terminal window on startup.
For example,
C:\ThanosDodd\Python3.6\pythonw.exe C:\\Python\Scripts\moveDLs.py
In order to make your script run continuously, you can use sched
for event scheduling:
The sched module defines a class which implements a general purpose
event scheduler
import sched
import time
event_schedule = sched.scheduler(time.time, time.sleep)
def do_something():
print("Hello, World!")
event_schedule.enter(30, 1, do_something, (sc,))
event_schedule.enter(30, 1, do_something, (s,))
event_schedule.run()
Now in order to kill a background process on Windows, you simply need to run:
taskkill /pid processId /f
Where processId
is the ID of the process you want to kill.
How to run python program in background to keep active window the same
Although pythonw
does run the script in the background without opening a command prompt window, your batch file does (even if this window is minimized). So you'll have to find the window that was active before your batch file was executed.
We use the EnumWindows function to iterate over our normal (i.e. visible and with a title) windows. The previous window is the second one in the enumeration. However, if you run the python script from a batch file, the command prompt window (as explained above) will be the previous window, so the one we're looking for is the third one in the enumeration.
#! python
import win32api
import win32gui
import win32con
monitors = win32api.EnumDisplayMonitors()
monitorsDict = {}
window_counter = [0]
def enumWindowsProc(hwnd, param):
if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowTextLength(hwnd) > 0:
window_counter[0] += 1
print(win32gui.GetWindowText(hwnd))
if window_counter[0] == 3:
window_counter[0] = hwnd
return False
return True
try:
win32gui.EnumWindows(enumWindowsProc,window_counter)
except:
pass
hwnd = window_counter[0]
currentWindowDimensions = win32gui.GetWindowRect(hwnd)
monitorInFocus = str(win32api.MonitorFromWindow(hwnd))
for i in range(len(monitors)):
monitorsDict[str(monitors[i][0])] = monitors[i][2]
maxWidth = (monitorsDict[monitorInFocus][2]-monitorsDict[monitorInFocus][0]) * .85
maxHeight = (monitorsDict[monitorInFocus][3]-monitorsDict[monitorInFocus][1]) * .85
x = int(currentWindowDimensions[0])
y = int(currentWindowDimensions[1])
newWidth = int(maxWidth + x)
newHeight = int(maxHeight + y)
newDimensions = (x, y, newWidth, newHeight)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, x, y, newWidth, newHeight, 0)
EnumWindows
calls the callback function pass to it until this returns False
. Unfortunately there's a bug in the win32 implementation: when the callback returns False
, EnumWindows
return 0
and this 0
is mistakenly considered an error and python will raise a run time error. A workaround is ignoring this error (as shown here) or just never return False
and thus enumerate the windows list till the very end although we've already found our window.
Instead of using a batch file, there's a more elegant way to invoke your script without creating an extra batch file: in the shortcut on your desktop, you can just insert the one line C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw
as the target. But remember, in this case we need to look for window number 2 instead of 3, so it'll be C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw
.
I tested both approaches (batch file and direct shortcut target) on Windows 7 and both work fine, invocated by short cut key or by clicking on the icon on the desktop.
Running Python Script as a Windows background process
On Windows, you can run a Python script in the background using the pythonw.exe
executable, which will run your program with no visible process or way to interact with it. You also cannot terminate it without a system monitor. More information on pythonw.exe
can be found in the answers to the question: pythonw.exe or python.exe?
Running program/function in background in Python
As I understand it, your goal is to start a background process in subprocess but not have the main program wait for it to finish. Here is an example program that does that:
$ cat script.py
import subprocess
subprocess.Popen("sleep 3; echo 'Done!';", shell=True)
Here is an example of that program in operation:
$ python script.py
$
$
$ Done!
As you can see, the shell script continued to run after python exited.
subprocess
has many options and you will want to customize the subprocess call to your needs.
In some cases, a child process that lives after its parent exits may leave a zombie process. For instructions on how to avoid that, see here.
The alternative: making subprocess wait
If you want the opposite to happen with python waiting for subprocess to complete, look at this program:
$ cat script.py
import subprocess
p = subprocess.Popen("sleep 3; echo 'Done!';", shell=True)
p.wait()
Here is an example its output:
$ python script.py
Done!
$
$
As you can see, because we called wait
, python waited until subprocess completed before exiting.
Run programs in background and redirect their outputs to file in real time
The -u
switch and the equivalent PYTHONUNBUFFERED
environment variable forces stdout to be unbuffered. Try this:
#!/bin/bash
python -u 1.py > 1.output &
python -u 2.py > 2.output &
python -u 3.py > 3.output &
or
#!/bin/bash
export PYTHONUNBUFFERED=yes
python 1.py > 1.output &
python 2.py > 2.output &
python 3.py > 3.output &
Note that -u
has side effects: read the doc to learn more.
Reference:
- https://docs.python.org/2/using/cmdline.html#cmdoption-u
- https://docs.python.org/2/using/cmdline.html#envvar-PYTHONUNBUFFERED
How to start another program and keep it running after Python script finishes?
The solution is actually easier then it seemed :]
We can just use os.popen
to run command in cmd/pipe, this will make those processes not dependent on the python process!
So let's just do it:
import os
os.popen("notepad.exe")
os.popen("notepad.exe")
print("Bye! Now it's your responsibility to close new process(es) :0")
this served as my inspiration, tho this solution works a little differently
Windows-only:
Also if you don't want to run several Popen
's (through os.popen
) to open one cmd.exe
and use it instead:
import subprocess
from time import sleep
path = r"C:\Windows\System32\cmd.exe"
p = subprocess.Popen(
[path],
bufsize=-1,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
def comunicate(process, message):
process.stdin.write(message)
process.stdin.flush()
comunicate(p, b'notepad.exe\n')
comunicate(p, b'notepad.exe\n')
sleep(0.1)
comunicate(p, b'exit\n') # closes cmd
print("Bye! Now it's your responsibility to close new process :0")
How to start a background process in Python?
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.
Related Topics
Unix Socket Credential Passing in Python
"Ssl Module in Python Is Not Available" When Installing Package with Pip3
Convert Base-2 Binary Number String to Int
Error: Pandas Hashtable Keyerror
Converting a String Representation of a List into an Actual List Object
How to Use Filter, Map, and Reduce in Python 3
Python: Changes to My Copy Variable Affect the Original Variable
Why Should I Make a Copy of a Data Frame in Pandas
How to One Hot Encode in Python
How to Direct Output to a File When There Are Utf-8 Characters
How to Capture Mouseevents and Keyevents Using Python in Background on Linux
How to Redirect the Stdout into Some Sort of String Buffer
Element-Wise Addition of 2 Lists
Converting a Pandas Groupby Output from Series to Dataframe
Replace Values in a Pandas Series via Dictionary Efficiently