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.
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.
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.
Hy guys, I have an error in systemctl that tells me that the python was not found. In my .service file below, I run celery-beat. In my tasks.py, I have a code snippet that uses os.system to run python code.
# My .service
[Unit]
Description=Celery Service
After=network.target
[Service]
Type=forking
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/my_project_folder
ExecStart=/bin/sh -c '/home/ubuntu/enviq/bin/celery -A projectdjango worker -l info -B --scheduler django_celery_beat.schedulers:DatabaseScheduler &'
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
# Error when execute sudo journalctl -xe
Apr 30 16:13:01 ip-172-31-17-187 sh[16228]: [2020-04-30 13:13:01,155: INFO/MainProcess] Received task: app_iq_option01.tasks.get_candles_tasks[d1d14df
Apr 30 16:13:01 ip-172-31-17-187 sh[16228]: sh: 1: python: not found
Apr 30 16:13:01 ip-172-31-17-187 sh[16228]: sh: 1: python: not found
# In this line I use the module os to call main_tasks.py
command = "python main_tasks.py {} {} {} '%s'".format(cred.email, cred.password, cred.max_samples)
command = command % coins
os.system(command)
When I run the command to run the celery through the terminal without using systemctl, it works normal. Anyone can help me with this? I really appreciate! It seems that systemd does not recognize my virtualenv (It calls venviq).
So i have a code that i'm trying to run and when it finish it should display a message to the user saying what changes have happend. This works fine if i run it on terminal. But when i add it to a cronjob nothing happens and no error is shown.
It seems to me that it is losing the display session, but cant figure it how to solve it. Here is the show message code:
def sendmessage(message):
subprocess.Popen(['notify-send', message])
return
I also tried this version:
def sendmessage(message):
Notify.init("Changes")
n = Notify.Notification.new(message)
n.show()
return
Which gives the error (only in background also):
cannot open display:
Activated service 'org.freedesktop.Notifications' failed: Process org.freedesktop.Notifications exited with status
Would be very thankful for any help or alternative given.
I had a similar issue running a system daemon, where I wanted the user to be notified about a network bandwidth upload being exceeded.
The program was designed to run under systemd but at a push also under upstart.
You may get some mileage out of my configuration files:
systemd - bandwidth.service file
[Unit]
Description=Bandwidth traffic monitor
Documentation=man:bandwidth(7)
After=graphical.target
[Service]
Type=simple
Environment="DISPLAY=:0" "XAUTHORITY=/home/#USER#/.Xauthority"
PIDFile=/var/run/bandwidth.pid
ExecStart=/usr/bin/dbus-launch /usr/sbin/bandwidth_logd
ExecReload=/bin/kill -HUP $MAINPID
User=root
[Install]
WantedBy=graphical.target
upstart - bandwidth.conf file
#
# These are the scripts that run when a network appears.
# Use this on an upstart system in /etc/init
# test for systemd or upstart system with
# ps -p1 | grep systemd && echo systemd || echo upstart
# better
# ps -p1 | grep systemd >/dev/null && echo systemd || echo upstart
# Using upstart the script will need to daemonise which is a bugger
# so test for it and import Daemon_server.py
description "Bandwidth upstart events"
start on net-device-up # Start a daemon or run a script
stop on net-device-down # (Optional) Stop a daemon, scripts already self-terminate.
# Automatically restart process if crashed
respawn
# Essentially lets upstart know the process will detach itself to the background
expect fork
#Set environment variables
env DISPLAY=":0"
export DISPLAY
env XAUTHORITY="/home/#USER#/.Xauthority"
export XAUTHORITY
script
# You can put shell script in here, including if/then and tests.
# replace #USER# with your name and ensure that you have .Xauthority in $HOME
/usr/sbin/bandwidth_logd
end script
You will note that in both configuration files the environment becomes key and #USER# is replaced by a real user name with a valid .Xauthority file in their $HOME directory.
In the python code I use the following to emit the message(import notify2).
def warning(msg):
result = True
try:
notify2.init("Bandwidth")
mess = notify2.Notification("Bandwidth",msg,'/usr/share/bandwidth/bandwidth.png')
mess.set_urgency(2)
mess.set_timeout(0)
mess.show()
except:
result = False
return result
I'm writing a 'simple' script to start up the django server, background it then start up firefox while I dev.
I've seen the </dev/null & trick and that works on the command line. But when I use it in my script it still hangs on the server starting. Backgrounding with ctrl-z and the bg command only backgrounds the script and not the command.
Is there a way I can pass django a 'Don't hog input' flag? Or I can background it inside the script in some way other than putting & at the end of it? Or just tell the script not to run it all in a separate session?
Here's my script in full (it's full on hard-core ugly, it might get prettified if I can get this to work):
SETTING_ENV=$1
if [ "$PWD" = "/home/$USERNAME/PROJECT/" ]; then
pid=$(for pid in $(pidof -x "python"); do ps -p $pid -o pid,cmd --no-heading; done| grep [m]anage|head -1|cut -d" " -f2)
if [ -z $pid ]; then
python ./manage.py runserver --settings=project.settings.$SETTING_ENV < /dev/null &
else
echo "Server still running on : $pid"
fi
pids=$(pidof -x firefox)
for pid in $pids; do
echo $pid
if [ -z $pid ]; then
echo "starting firefox"
firefox --new-window localhost:8000 &
else ecjp "Firefox already running on pid: $pid"
fi
done
else
echo "$PWD is not /home/$USERNAME/PROJECT";
fi
You can put all your command in parenthesis like this :
(python ./manage.py runserver --settings=project.settings.$SETTING_ENV < /dev/null &)
When you run a command between parentheses it will create a new sub-shell so when you will quit the shell the command will continues to run.
Or you can also use disown or nohup :
python ./manage.py runserver --settings=project.settings.$SETTING_ENV < /dev/null &
disown
-
nohup python ./manage.py runserver --settings=project.settings.$SETTING_ENV < /dev/null &