I have a setup where I have a servercabinet with an external display that shows various system information. I only want it to turn on when I am present though, and I have made it soundactivated using SoundMeter https://github.com/shichao-an/soundmeter and a cheap USB microphone. When run manually everything works as it sohuld, but when i try to run it as a systemd service or a cronjob, it wont execute the second script that starts the display. From the logs I can see that Soundmeter works as it should, but it doesn't fire up the display.
Systemd service:
[Unit]
Description=Soundmeter
[Service]
Type=simple
Restart=always
#RestartSec=120
User=pi
ExecStart=/usr/local/bin/soundmeter -t +25 -a exec -e /opt/sysdroidUHHD/trigger.sh
[Install]
WantedBy=multi-user.target
Cronjob
#reboot /usr/local/bin/soundmeter -t +25 -a exec -e /opt/sysdroidUHHD/trigger.sh &
Contents of trigger.sh
#!/bin/bash
python3 /opt/sysdroidUHHD/sysdroid_main.py
exit 0
Any and all help is appreciated.
Remove that exit 0 from trigger.sh. Make sure your sysdroid_main.py starts some server or daemon that won't exit.
Related
I know how to autostart a python script (or so I thought). But I want a programm or something, if my python script is not running anymore, it should start the script again. Has anyone a idea how to do this?
Edit:
I tried running it as a service but that didnt work.
import bluetooth
import pygame
pygame.mixer.init()
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
port = 22
server_sock.bind(("",port))
server_sock.listen(1)
client_sock,address = server_sock.accept()
print ("Verbindung Hergestellt mit: ", address)
while True:
recvdata = client_sock.recv(1024)
print ("Nachricht bekommen: %s" % recvdata)
pygame.mixer.pause()
if (recvdata == b"h"):
sound = pygame.mixer.Sound('/home/maxi/Desktop/test.wav')
playing = sound.play()
if (recvdata == b"p"):
sound = pygame.mixer.Sound('/home/maxi/Desktop/test2.wav')
playing = sound.play()
if (recvdata == b"k"):
break
client_sock.close()
server_sock.close()
My startscript is:
[Unit]
Description=MaxiTest
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3 /home/maxi/Desktop/btsound1.py
[Install]
WantedBy=multi-user.target
You can search more about how a python script can perform as a service or daemon. There are many solutions in this link:
How to make a Python script run like a service or daemon in Linux
Between all solutions, I prefer 3 of them (I'm not very familiar with raspberry-pi, so check compatibility):
Cronjob: You can create a cronjob for the script and the OS will run it every x seconds/minutes/... automatically and periodically.
Systemctl/Systemd: Create a custom service file for your script and start and enable it in Systemd. A complete guide is here:
https://medium.com/codex/setup-a-python-script-as-a-service-through-systemctl-systemd-f0cc55a42267
You chose systemd (after editing);
In /PATH_project/ create 2 bash scripts like this:
#!/bin/bash
# This is start.sh
cd /home/maxi/Desktop/
/usr/bin/python3 btsound1.py
And create stop.sh:
#!/bin/bash
for KILLPID in `ps ax | grep ‘myservice’ | awk ‘{print $1;}’`; do
kill -9 $KILLPID;
done
Then give execution permission to both files using:
chmod a+x start.sh
chmod a+x stop.sh
Then create a myservice.service file in /etc/systemd/system :
[Unit]
Description=myservice service
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=simple
Restart=always
ExecStart=/bin/bash /home/maxi/Desktop/start.sh
ExecStop=/bin/bash /home/maxi/Desktop/stop.sh
RestartSec=5
TimeoutSec=60
RuntimeMaxSec=infinity
PIDFile=/tmp/mydaemon.pid
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl start myservice.service
sudo systemctl status myservice.service
Benefits of using such bash scripts is that you can handle some more things in this way. For example if you are using a virtual environment, you can use source activate in start.sh file before running the script.py .
Supervisord: Install Supervisor and create a supervisord.conf file for your script. A good guide is here:
https://csjourney.com/managing-processes-with-supervisor-in-depth-tutorial/
I found what was the problem. I used rc.local and started the program 10 seconds after boot. The system needed time first to set up before I could start the script.
Here is the current Unit definition:
[Unit]
Description=Run control script for chicken coop door via python
After=multi-user.target
Requires=network.target
[Service]
Type=idle
User=pi
ExecStart=/bin/python3.9/home/pi/Documents/Coop_Door_Final.py
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
You can't directly show the output of a process controlled by systemd on a terminal (at least not with extra shenanigans), since systemd redirects regular stdout/stderr output to the journal.
However, you can set up journalctl to print out that output and follow along as more appears, and run that on your console.
journalctl -f -u yourunitname
I currently am running a program through Thonny, and I want to make the pi autoboot that program whenever it turns on. I currently have the pi 4, and the code is run on Python3. Have tried many ways to autoboot such as using rc local, and bash rc, but none seem to work.
I recommend using the autostart file.
Edit the following file:
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
The default should look something like:
#lxpanel --profile LXDE-pi
#pcmanfm --desktop --profile LXDE-pi
#xscreensaver -no-splash
Add the command to run your script utilizing the # prefix and save. The new autostart file should look like:
#lxpanel --profile LXDE-pi
#pcmanfm --desktop --profile LXDE-pi
#xscreensaver -no-splash
#python3 /home/pi/your_script.py
More info: https://www.raspberrypi.org/forums/viewtopic.php?t=294014
By using things like .bashrc, your program will only get executed when you open a command prompt or terminal.
You can use systemd services:
create a file your_service.service in /etc/systemd/system/ (you need to be root, so use sudo). The filename will be the name of your service, without the .service extension (in this case your service will be named your_service)
put this in it (without the comments):
[Unit]
Description=A short description of your service
After=network.target # <-- put this if your script needs network, otherwise you can omit this line
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always # use this to always restart the script if the process ends. If your script only needs to run once at startup and is not a daemon, don't use this.
RestartSec=1
User=root # user account used to run the service
ExecStart=python3 /path/to/your/script.py
[Install]
WantedBy=multi-user.target
Then, you can start your script with this command:
sudo systemctl start your_service
You can finally enable the service to be run automatically at startup with this command:
sudo systemctl enable your_service
You can find more documentation / tutorials on systemd services and on all the available options in the following links:
https://medium.com/#benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6
https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
https://www.freedesktop.org/software/systemd/man/systemd.service.html
https://wiki.archlinux.org/title/Systemd
I have a python script. Script have selenium with Chrome and go to a website, take data and put in CSV file.
This is a very long work.
I put the script on the server. And run. All work.
But I need script work in the background.
chmod +x createdb.py
nohup python ./createdb.py &
And I see
(env)$ nohup ./createdb.py &
[1] 32257
(env)$ nohup: ignoring input and appending output to 'nohup.out'
Press Enter.
(env)$ nohup ./createdb.py &
[1] 32257
(env)$ nohup: ignoring input and appending output to 'nohup.out'
[1]+ Exit 1 nohup ./createdb.py
Then it runs and immediately writes errors to the file, that Chrome did not start or there was no click.
I want to remind you that if you start without nohup, then everything will work.
What am I doing wrong? How to run a script?
Thank you very much.
You could create a background daemon (service)
You taged Ubuntu 16.04 it means you got systemd, for more information on how to set it up, please visit this link
create a file called <my_service>.system
and put it there: /etc/systemd/system
you systemd unit could look like this:
[Unit]
Description=my service
After=graphical.target
[Service]
Type=simple
WorkingDirectory=/my_dir
ExecStart=python my_script.py
[Install]
WantedBy=multi-user.target
then all you have to do is, reload systemd manage and start your service:
sudo systemctl daemon-reload
sudo systemctl myservice start
You can use the screen command, it works perfectly.
Here is a very good link: https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/
You can use a simple command, from the env directory:
(env)$ python /path/to/createdb.py > logger.txt 2>&1 &
This will help for storing the program logs in a defined file called "logger.txt"
I wrote a systemd script and python script for auto detect mounting.
Systemd Script:
[Unit]
Description=TAD_Client - TAD WebService
After=network.target
[Service]
User=root
Type=forking
ExecStart=/data/.services/autoconfig.sh start
ExecReload=/data/.services/autoconfig.sh restart
ExecStop=/data/.services/autoconfig.sh stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Shell Script(part):
export SHELL=/bin/bash
case "$1" in
"start" )
echo "configuration service start"
exec "/usr/bin/python" /data/.services/AutoConfiguration.py run &
;;
"stop" )
echo "configuration service stop"
exec "/usr/bin/python" /data/.services/AutoConfiguration.py stop
;;
"restart" )
echo "restart configuration service"
exec "/usr/bin/python" /data/.services/AutoConfiguration.py stop
exec "/usr/bin/python" /data/.services/AutoConfiguration.py run &
;;
Python Script(part):
def mount_peu_server(self):
mount_command = 'mount -t nfs ' + server_ip.addr + ':/mnt /mnt'
p = subprocess.Popen(mount_command, stdout=subprocess.PIPE)
out, err = p.communicate()
self.log_error(out)
self.log_error(err)
When I use systemd to start the script as a service, the mount command is not working, but if i execute the python script file directly, the mount command can be executed successfully.
I have checked the output and err output, subprocess returns nothing. I think it could be a privilege problem, but this service is running by root user, which should not require any privilege anymore.