Daemonize a Python script on Raspbian Buster - python

I am working on an RFID-based access control system for which I have a working python script. For some specific details if they matter, the main processing is done on a pi zero w, which is connected by USB to a microcontroller that handles the input from the RFID module and sends it to the pi in string format for simplicity. The pi then compares the string received to a yaml file and a schedule and uses GPIO to switch on or off a door strike using a power supply. The issue I'm running into is that the script stops running after about 30 minutes, and I'm not quite sure why, but I think the ideal solution in any case is to daemonize it, because a cron job is too subject to failure and a daemon seems very appropriate for this use. Does anyone have any suggestions for daemonizing the script such that it will start on boot and restart itself if it detects a failure or that it is no longer running?

As larsks said, you can create systemd service
sudo nano /etc/systemd/system/yourscript.service
This file should be something like this (read the documentation for more information):
[Unit]
Description=My cool script
After=multi-user.target
[Service]
User=root
WorkingDirectory=/path/to/your/script/directory/
Restart=on-failure
RestartSec=5s
ExecStart=/usr/bin/python3 your_script.py
StandardOutput=append:/var/log/your_script.log
StandardError=append:/var/log/your_script.log
SyslogIdentifier=coolawesomescript
[Install]
WantedBy=multi-user.target
Then enable and start it:
foo#bar:~$ sudo systemctl enable yourscript
foo#bar:~$ sudo systemctl start yourscript
Now your script will automatically restart when it crashes
You can check if your script actually works by typing sudo systemctl status yourscript

Related

How to detach process in Ubuntu

I'm running a chatbot on Ubuntu server on Amazon EC2 instance. I want to be able to run the python3 program even after closing the pUTTY window. So far I've tried 'Ctrl+a, d' as well as 'Ctrl+z, bg'. However both methods did not seem to work after closing the pUTTY window. I referenced the following youtube video:
Would really appreciate any help!
I hope the question is "how to keep the python script running even after closing the putty"
IMO, you can use 2 approaches here.
Use nohup
The unix command nohup can make your program run in background even after exiting the terminal.
You can run it like
nohup python3 LP_poolVol.py > /dev/null &
nohup will make the script running and the & at the end will make it in
background
Make the script a service
Run the script as a linux service which you can start and stop using the systemctl
You can create a service descriptor file pool-vol.service with contents similar to below.
[Unit]
Description=Pool Vol Service
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3 <path-to>/LP_poolVol.py
[Install]
WantedBy=multi-user.target
Then copy this service file to /etc/systemd/system/. And then install it via the commands below
sudo systemctl daemon-reload
sudo systemctl enable pool-vol.service
sudo systemctl start pool-vol
Now your app is running as a service. You can stop or restart it using the systemctl itself like
sudo systemctl start pool-vol

run a python script on raspberry pi turned on

I am working on raspberry pi 3 about 3 months , I had a problem when I started working with it.
I couldn't find an efficient and safe way to run a python script on raspberry when it turns on(without monitor and mouse and keyboard).At the moment I have added "$sudo run myscript.py &" at /etc/profile but sometimes when I turn it on my script doesn't run until I connect monitor and mouse and keyboard to it and run the script with GUI and after that it works fine (again without mouse and keyboard).
I want to know is there any solution that I will be sure my script will run after I turn raspberry pi on?
Thanks a lot
You will want to setup a service and user sudo service <my_service> [start, stop, restart] to get it working on startup. See here for reference.
The /etc/profile is executed when new shell session in being started, so unless you start at least single shell session your script will not be run. Moreover it will be terminated when session stops, and if you start multiple sessions then the script will also be started for each session, which is probably not what you want.
Depending on your init system you would need to create SysVinit or systemd service. Assuming you use systemd based distro (which is currently default for most Linux distributions) you need to do following:
Step 1: Place your script in location from which it will be executed by service. For example /usr/local/bin/ may be good choice.
Step 2: Create service file. Assuming you want to name it myscript.service, create file at following path /etc/systemd/system/myscript.service with following content:
[Unit]
Description=myscript
[Service]
ExecStart="/usr/bin/python /usr/local/bin/myscript.py"
[Install]
WantedBy=multi-user.target
Step 3: Reload systemd daemon and enable your service:
systemctl daemon-reload
systemctl enable myscript
Now after you restart your system, your service should be automatically started. You can verify that using command systemctl status myscript, which returns service status.

Run Python headless on local server

So, here is my little problem:
I have a small python program and have to run it 24/7 with internet access. So using my laptop is not really a solution. But I can use a local server. My program is saved on the server. Is there a way to start the program headless on the server, so it can run for a long period of time?
Thanks
This post assumes you are using linux. If this is not the case, I will still keep this answer around for anyone else. The general Principles will apply to any OS regardless.
While setsid is one way to put a program into the background, it is usually not what you want for a number of reasons:
If you ssh into the server again, there is no easy way to see the output of the program. Any output will not be kept.
If the program crashes, it won't be restarted.
If the server reboots, it won't be started.
There is no easy way to see the status, stop or restart it.
One slightly better method would be to use tmux (or the older screen). These can be used to detach a process, but still have access to it's output. (see this answer).
However, if you want to do things correctly, you should use a process manager/supervisor, such as systemd or supervisord.
For systemd, you can create the following file: /etc/systemd/system/yourprogramname.service
Inside it, place the following text:
[Unit]
Description=YourDescription
[Service]
ExecStart=/usr/bin/python3 /your/full/script/location.py
Restart=always
[Install]
WantedBy=multi-user.target
(These files support a number of additional options, you can view them at: http://0pointer.de/public/systemd-man/systemd.service.html)
Then reload the units with systemctl daemon-reload and enable your unit at boot with systemctl enable yourprogramname.service.
You can then:
Start it: systemctl start yourprogramname
Retart it: systemctl restart yourprogramname
Stop it: systemctl stop yourprogramname
Get the status: systemctl status yourprogramname
View the full logs: journalctl -u yourprogramname
(these commands all require sudo)

Automatically start a program at Raspbian - Raspberry Pi 3

I'm using a Raspberry Pi 3 with Raspbian distribution.
I've written a script in Python 3 and I would need to start it up automatically just when system boots up, without logging in.
I would recommend using systemd to achieve this. Take for example your python script is called hello.py.
Create a systemd service file at /lib/systemd/system/hello.service:
[Unit]
Description=hello.py service file
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/python /dir/to/your/hello.py
Restart=always
[Install]
WantedBy=multi-user.target
The full list of commands and functions for the systemd service file can be found here.
Add appropriate permissions to the .service file: sudo chmod 644 /lib/systemd/system/hello.service
Reload the systemd daemon: sudo systemctl daemon-reload
Enable the hello systemd service: sudo systemctl enable hello.service
You can check that your service is running by using the command: sudo systemctl status hello.service and check for any errors using sudo journalctl
Raspberry PI has quite good support. Tasks can be schedualed with usage of "crontab" command.
You can find documentation on: Documentation
Within this documentation you have example for running "python" script on Raspberry Pi reboot.
Hope it helps!

Python Script that was called from bash startup script stops after 20mins of running,

I have a python script that has a While True: in it that I would like to have run on startup on a raspberry pi running Jessie.
So far I have a startup bash script in /etc/init.d called startup.sh which contains
sudo python3 /home/pi/Desktop/Scripts/bluez3.py &
When the raspberry pi starts up, the script does run but after 20 minutes the script seems to stop. I have logging in my script and the time-stamp stops exactly 20 mins in.
I did some reading and I think the best option would be to create the python script as a service on the raspberry pi. However, I have not been able to find a decent tutorial about how to do this (and my lack of python knowledge).
My question is, is there another way to resolve my problem or does anyone know of a good tutorial on how to make the python script into a service.
Thanks!
given the name of your script, I'm guessing it's related to some bluetooth stuff. It's likely that after 20 min, whatever you're checking/needing in your script gets unaccessible and throws an exception or something like that. Like a resource being locked, or a bt device being disconnected or a module being unloaded or unavailable or [insert edge case reason here]…
that being said, in between creating a systemd service, you can first play with supervisorctl which is just an apt install supervisor away.
then if you really want to launch it as a service, you can find plenty of examples in /lib/systemd/system/*.service, like the following:
[Unit]
Description=Your service
Wants=
After=bluetooth.target # I guess you need bluetooth initialised first
[Service]
ExecStart=/usr/bin/python3 /home/pi/Desktop/Scripts/bluez3.py
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always
[Install]
WantedBy=multi-user.target
which I customized from the sshd.service file 😉

Categories