Introduction

If you want to run a python script in the background you can use an ampersand(&). But at first, we need to prepare our script for this.

For example, we have a python file my_script.py. At first, we need to add execution permission for this file using the next command:

chmod +x my_script.py

Then I recommend adding a shebang line to the top of this file. This allowed you don't indicate in the terminal that it is a python script.

#!/usr/bin/env python3

Now we need some logic that will show us that the script is running in the background. For example, a simple script that will have been printing time during the next ten seconds.

Script content:

 #!/usr/bin/env python3

from datetime import datetime

start_time = datetime.now()
print(f"Start time: {datetime.now().strftime('%H:%M:%S')}")

interval = 10

while interval != 0:
    if (datetime.now() - start_time).seconds == 1:
        start_time = datetime.now()
        print(f"Current time: {datetime.now().strftime('%H:%M:%S')}")
        interval -= 1

Using only ampersand (&)

For running the script use the next command:

your/path/my_script.py > output.log &

We save the script's output to the log file, so after running this command we will get output like this in the terminal:

[1] 3010186

This is a process id (PID). If you want to stop the script before its ending you can use the kill command:

kill PID

It is also possible to kill the process by using pkill command. If you run a few scripts with the same name they all will be stopped.

pkill -f my_script.py

We can see our process using the next command:

ps ax | grep my_script.py

Command output:

3010186 pts/0    R      0:03 python3 ./my_script.py
3012286 pts/1    S+     0:00 grep --color=auto my_script.py

After finishing the process all script output will be saved to output.log. It has the next content:

Start time: 10:46:21
Current time: 10:46:22
Current time: 10:46:23
Current time: 10:46:24
Current time: 10:46:25
Current time: 10:46:26
Current time: 10:46:27
Current time: 10:46:28
Current time: 10:46:29
Current time: 10:46:30
Current time: 10:46:31

The background script seems to work perfectly, but it's not quite true. For example, if you use ssh session connection, the disconnect will stop our script. As a solution, you could use nohup or a better screen. This allows us to return to the script after reconnecting the session.

Using the 'screen' command for background scripts

At first, you need to install the screen. Use the next command for this:

sudo apt install screen

Now we can run our script using the screen command. We need a little to modify the command for the identical logging as in the previous heading. For that, we need to add the next keys: -L for resolving logging and -Logfile path/to/filename.log to indicate log file (by default screenlog.0)

screen -L -Logfile ./output.log ./my_script.py &

Despite the screen output, logging still saves to our log file. 

Let's check the process list during performing the screen command using the next command:

ps ax | grep my_script.py

Command output:

3038184 pts/0    S      0:00 screen -L -Logfile ./output.log ./my_script.py
3038185 ?        Ss     0:00 SCREEN -L -Logfile ./output.log ./my_script.py
3038186 pts/3    Rs+    0:03 python3 ./my_script.py
3038214 pts/1    S+     0:00 grep --color=auto my_script.py

You can also detach the screen using Ctrl + a and also return back to the screen using the command screen -r.

Want to get simple and clear knowledge about programming, devops and other aspects of software development? Read a Devforth blog, the Devforth is a software development team of true professionals who know how to code well and most excitable thing - they share their knowledge approaches and tools in "Like I am five" mode to attract more audience and improve awareness. There are awesome posts about best practices like Critical server alerts setup, Simple and efficient Docker builds with self-hosted Docker registry, and many many more.