I have Python script bgservice.py
and I want it to run all the time, because it is part of the web service I build. How can I make it run continuously even after I logout SSH?
12 Answers
Run nohup python bgservice.py &
to get the script to ignore the hangup signal and keep running. Output will be put in nohup.out
.
Ideally, you'd run your script with something like supervise
so that it can be restarted if (when) it dies.

- 29,597
- 13
- 90
- 129
-
21when I run command with nohup and &, I get message `nohup: ignoring in put and appending output to `nohup.out'` and when I press enter the process exits with status 1. What's going on? – Santosh Ghimire Dec 07 '13 at 15:03
-
2read the output in nohup.out. in my case, it was a permissions problem, i needed to use sudo – mxns May 06 '14 at 05:46
-
2and how to stop the bgservice after it is run in this method? – fire in the hole Feb 08 '18 at 10:16
-
1@Shaegorath save the pid somewhere so that you can send signals to the process later. in some shells (bash, zsh, etc.) after you do `somecommand &` it will print the pid like `[1] 12345`. otherwise you can use `$!`. – Tony Beta Lambda Mar 28 '18 at 04:17
-
1I have been looking at nohup as the recommended solution to the question, but I see that the output file nohup.out is generated after the python script ends. It does not allow you to append the results as the python script runs. I also don't see how you provide inputs to the scripts using nohup. I haven't tested the behavior of threads but it is not a good solution for me for the above reasons. So I will keep looking. Any solutions or suggestions? I want to interact with my application when I log back in using ssh. – Sodanetworks Aug 13 '21 at 15:25
If you've already started the process, and don't want to kill it and restart under nohup, you can send it to the background, then disown it.
Ctrl+Z
(suspend the process)
bg
(restart the process in the background
disown %1
(assuming this is job #1, use jobs
to determine)

- 1,267
- 11
- 16
Running a Python Script in the Background
First, you need to add a shebang line in the Python script which looks like the following:
#!/usr/bin/env python3
This path is necessary if you have multiple versions of Python installed and /usr/bin/env
will ensure that the first Python interpreter in your $$PATH
environment variable is taken. You can also hardcode the path of your Python interpreter (e.g. #!/usr/bin/python3
), but this is not flexible and not portable on other machines. Next, you’ll need to set the permissions of the file to allow execution:
chmod +x test.py
Now you can run the script with nohup which ignores the hangup signal. This means that you can close the terminal without stopping the execution. Also, don’t forget to add &
so the script runs in the background:
nohup /path/to/test.py &
If you did not add a shebang
to the file you can instead run the script with this command:
nohup python /path/to/test.py &
The output will be saved in the nohup.out
file, unless you specify the output file like here:
nohup /path/to/test.py > output.log &
nohup python /path/to/test.py > output.log &
If you have redirected the output of the command somewhere else - including /dev/null
- that's where it goes instead.
# doesn't create nohup.out
nohup command >/dev/null 2>&1
If you're using nohup
, that probably means you want to run the command in the background by putting another &
on the end of the whole thing:
# runs in background, still doesn't create nohup.out
nohup command >/dev/null 2>&1 &
You can find the process
and its process ID
with this command:
ps ax | grep test.py
# or
# list of running processes Python
ps -fA | grep python
ps
stands for process status
If you want to stop the execution, you can kill it with the kill command:
kill PID

- 6,823
- 1
- 50
- 42
-
what if I want it still accept standard input from ssh terminal before I exit the ssh? – Luk Aron Oct 09 '21 at 17:18
-
The topic talks about the background and not about the standard execution. Anyway, I think your answer is in this [great documentation](https://docs.python.org/3/library/subprocess.html). – Milovan Tomašević Oct 09 '21 at 22:45
You could also use GNU screen which just about every Linux/Unix system should have.
If you are on Ubuntu/Debian, its enhanced variant byobu is rather nice too.

- 5,323
- 3
- 36
- 34

- 360,940
- 56
- 644
- 725
You might consider turning your python script into a proper python daemon, as described here.
python-daemon is a good tool that can be used to run python scripts as a background daemon process rather than a forever running script. You will need to modify existing code a bit but its plain and simple.
If you are facing problems with python-daemon, there is another utility supervisor that will do the same for you, but in this case you wont have to write any code (or modify existing) as this is a out of the box solution for daemonizing processes.

- 1
- 1

- 5,323
- 3
- 36
- 34
-
1giving a brief explanation about how the problem can be solved is generally a good idea. – Nikhil Sahu Oct 08 '16 at 12:25
Alternate answer: tmux
- ssh into the remote machine
- type
tmux
into cmd - start the process you want inside the
tmux
e.g.python3 main.py
- leaving the
tmux
session byCtrl+b
thend
It is now safe to exit the remote machine. When you come back use tmux attach
to re-enter tmux
session.
If you want to start multiple sessions, name each session using Ctrl+b
then $
. then type your session name.
to list all session use tmux list-sessions
to attach a running session use tmux attach-session -t <session-name>
.

- 475
- 5
- 17
Here is a simple solution inside python using a decorator:
import os, time
def daemon(func):
def wrapper(*args, **kwargs):
if os.fork(): return
func(*args, **kwargs)
os._exit(os.EX_OK)
return wrapper
@daemon
def my_func(count=10):
for i in range(0,count):
print('parent pid: %d' % os.getppid())
time.sleep(1)
my_func(count=10)
#still in parent thread
time.sleep(2)
#after 2 seconds the function my_func lives on is own
You can of course replace the content of your bgservice.py
file in place of my_func
.

- 1,009
- 1
- 9
- 10
-
2Maybe it is necessary to catch the SIGHUP signal. Then add signal.signal(signal.SIGHUP, handler) in your block. – Chouettou Jan 19 '17 at 10:01
-
Yeah, this doesn't seem to work here. The child dies when the parent exits. – olejorgenb May 12 '21 at 10:51
Try this:
nohup python -u <your file name>.py >> <your log file>.log &
You can run above command in screen and come out of screen.
Now you can tail logs of your python script by: tail -f <your log file>.log
To kill you script, you can use ps -aux and kill commands.

- 659
- 9
- 23
-
what if I want it still accept standard input from ssh terminal before I exit the ssh? – Luk Aron Oct 09 '21 at 17:18
The zsh shell has an option to make all background processes run with nohup.
In ~/.zshrc
add the lines:
setopt nocheckjobs #don't warn about bg processes on exit
setopt nohup #don't kill bg processes on exit
Then you just need to run a process like so: python bgservice.py &
, and you no longer need to use the nohup command.
I know not many people use zsh, but it's a really cool shell which I would recommend.

- 22,013
- 7
- 46
- 42
If what you need is that the process should run forever no matter whether you are logged in or not, consider running the process as a daemon.
supervisord is a great out of the box solution that can be used to daemonize any process. It has another controlling utility supervisorctl
that can be used to monitor processes that are being run by supervisor.
You don't have to write any extra code or modify existing scripts to make this work. Moreover, verbose documentation makes this process much simpler.
After scratching my head for hours around python-daemon, supervisor is the solution that worked for me in minutes.
Hope this helps someone trying to make python-daemon work

- 2,463
- 2
- 32
- 48
You can also use Yapdi:
Basic usage:
import yapdi daemon = yapdi.Daemon() retcode = daemon.daemonize() # This would run in daemon mode; output is not visible if retcode == yapdi.OPERATION_SUCCESSFUL: print('Hello Daemon')

- 21
- 1
- 1