I followed multiple tutorials available on stackoverflow about starting a python script at startup but none of them works.
I need to activate a virtualenv then start a flask server
I tried
init.d method
I made an start.sh in /etc/init.d/
#!/bin/sh
### BEGIN INIT INFO
# Provides: skeleton
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $portmap
# Should-Stop: $portmap
# X-Start-Before: nis
# X-Stop-After: nis
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: true
# Short-Description: Example initscript
# Description: This file should be used to construct scripts to be
# placed in /etc/init.d.
### END INIT INFO
cd /home/ion/
source /home/ion/py35/bin/activate
cd /home/ion/Desktop/flask/
nohup python main.py &
echo "Done"
Its permissions are chmod at +x
ion#aurora:/etc/init.d$ ll start.sh
-rwxr-xr-x 1 root root 625 Jun 25 19:10 start.sh*
Went to /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/etc/init.d/start.sh
exit 0
Didn't work
cronjob method
sudo crontab -e
and appended
#reboot sh '/etc/init.d/start.sh'
Didn't worked either , where am I wrong?
Manual triggered logs
(py35) ion#aurora:~/Desktop/flask$ python main.py
WARNING:tensorflow:From /home/ion/Desktop/flask/encoder.py:57: calling l2_normalize (from tensorflow.python.ops.nn_impl) with dim is deprecated and will be removed in a future version.
Instructions for updating:
dim is deprecated, use axis instead
2018-06-25 19:34:05.511943: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://localhost:5505/ (Press CTRL+C to quit)
* Restarting with stat
1) Don't use old "init.d" method. Use something modern. If you have Ubuntu 15.04 and higher, you can use Systemd to create daemon that will be started automatically at startup. If you have for example Ubuntu older than 15.04 - use Upstart.
For Systemd:
Create unit file in /lib/systemd/system/you_service_name.service with the following content (as far as I can see your python script doesn't spawn new process while running, so Type should be simple. More info here):
[Unit]
Description=<your_service_name>
After=network.target network-online.target
[Service]
Type=simple
User=<required_user_name>
Group=<required_group_name>
Restart=always
ExecStartPre=/bin/mkdir -p /var/run/<your_service_name>
PIDFile=/var/run/<your_service_name>/service.pid
ExecStart=/path/to/python_executable /path/to/your/script.py
[Install]
WantedBy=multi-user.target
Save this file and reload systemd:
sudo systemctl daemon-reload
Then add your service to autostart:
sudo systemctl enable you_service_name.service
you should see that Systemd created required symlinks after enable action.
Reboot and see if it's up and running (ps aux | grep python or sudo systemctl status you_service_name.service). If there is something weird - check Systemd journal:
sudo journalctl -xe
UPD:
To launch your python script in desired virtualenv, just use this expression in your service unit file:
ExecStart=/venv_home/path/to/python /venv_home/path/to/your/script.py
2) You can also use crontab, but you need to specify full path for desired shell there, for example:
#reboot /bin/bash /path/to/script.sh
If you need additional help - just let me know here.
Related
As my first batch script, I want to run my backend and frontend with just one script. My backend is in python with Django and my frontend is in react. I, therefore, have to processes I need to run. But I don't know how to run them in parallel as I need to start a virtual environment in python first.
I don't understand how it would log the server logs. Is there an option to make two terminal windows or a new terminal tab? Or would it log in to one terminal together?
#!/bin/bash
DJANGODIR=/Users/usr/Desktop/programming/app/django
REACTDIR=/Users/urs/Desktop/programming/app/react
# START REACT FRONTEND
echo Starting React Server
# Option 1
# cd $REACTDIR
# npm start
# Option 2
# start app from any directory without cd into it
# npm --prefix $REACTDIR run start
# START DJANGO BACKEND
echo Starting Django Server
# cd $DJANGODIR
# Start virtual environment
# source venv/bin/activate
# Start Server
# python3 manage.py runserver
# Activating and running in one command
# source venv/bin/activate python3 manage.py runserver
# Here is where I'm not knowing how to run them in parallel
source venv/bin/activate python3 manage.py runserver & npm --prefix $REACTDIR run start
Have you tried with the pipe operator? Pipe operator explained
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 wanted to put my python code in boot in raspberry pi.
I tried rc.local, ./bashrc but while booting program is working & I am using opencv + camera +voice command. That's not working in boot.
Please give me a way to run voice + camera + opencv + python code in boot.
I would suggest to make it run as a service as mentioned in method 4 of following article:
https://www.dexterindustries.com/howto/run-a-program-on-your-raspberry-pi-at-startup/
Step 1– Create A Unit File
Open a sample unit file using the command as shown below:
sudo nano /lib/systemd/system/sample.service
Add in the following text :
[Unit]
Description=My Sample Service
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/bin/python /home/pi/sample.py
[Install]
WantedBy=multi-user.target
You should save and exit the nano editor.
This defines a new service called “Sample Service” and we are requesting that it is launched once the multi-user environment is available. The “ExecStart” parameter is used to specify the command we want to run. The “Type” is set to “idle” to ensure that the ExecStart command is run only when everything else has loaded. Note that the paths are absolute and define the complete location of Python as well as the location of our Python script.
In order to store the script’s text output in a log file you can change the ExecStart line to:
ExecStart=/usr/bin/python /home/pi/sample.py > /home/pi/sample.log 2>&1
The permission on the unit file needs to be set to 644 :
sudo chmod 644 /lib/systemd/system/sample.service
Step 2 – Configure systemd
Now the unit file has been defined we can tell systemd to start it during the boot sequence :
sudo systemctl daemon-reload
sudo systemctl enable sample.service
Reboot the Pi and your custom service should run:
sudo reboot
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 trying to follow the tutorial at http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html. I am working with an ubuntu 14.4 instance on amazon EC2. I'm trying to deploy a django app I've developed locally with python3. So far I've got the app working following the tut as long as I manually ssh in , turn on the virtualenv and then turn on uwsgi, using :
workon env1
uwsgi --ini /home/ubuntu/mysite_uwsgi.ini
I noticed however that when I tried to send a request to the app this morning, that I was getting:
errno 5 input/output error
This was solved my manually sshing in and executing the 2 lines above. I don't understand how this works exactly , but somehow my virtualenv and uwsgi were deactivated after I logged off. I need to keep them active so that all requests can be funneled to my app. I don't know how to do this. Following the tut above , I've modified /etc/rc.local to:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
workon myenv
uwsgi --ini /home/ubuntu/mysite_uwsgi.ini
exit 0
Will this solve my problem. If not what should I do?
You can daemonize the process:
env = DJANGO_SETTINGS_MODULE=mysite.settings # set an environment variable
pidfile = /tmp/project-master.pid # create a pidfile
harakiri = 20 # respawn processes taking more than 20 seconds
limit-as = 128 # limit the project to 128 MB
max-requests = 5000 # respawn processes after serving 5000 requests
"uwsgi --ini uwsgi.ini --daemonize=/var/log/yourproject.log # background the
If you've followed the rest of the doc and are ready to run in "emperor" mode, add this to /etc/rc.local before exit 0:
/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data