I am currently running ngrock and a python app concurrently on a specific port to text my raspberry pi, and have it respond accordingly to my message via Twilio. Each time my raspberry pi boots up, or reboots, I need to manually start the services again with ./ngrok http 5000 and python /path/to/file/app.py. To avoid that, I edited my cron jobs as follows, and wrote a script called startService.py. However, it doesn't seem to be functioning properly, as I do not receive answers to texts after reboot. Any ideas?
Cron:
# m h dom mon dow command
*/5 * * * * python /rasp/system/systemCheck.py
#reboot python /Rasp/system/twilio/startService.py &
startService.py
import os
os.system('/./ngrok http -subdomain=ABC123 5000')
os.system('python /Rasp/system/twilio/starter/app.py')
You did not mention your OS, assuming your OS using Upstart for boot you can create upstart script to start then your process will automatically spawn at boot or when the process die. For ngrok, create a file /etc/init/ngrok.conf
# Ngrok
#
# Create tunnel provided by ngrok.io
description "Ngrok Tunnel"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5
umask 022
exec /ngrok http -subdomain={{My Reserved Subdomain}} 5000
Now it will automaticlaly start at boot. If you want to start manually just issue command.
$ sudo service ngrok start
Just for suggestion, putting your binary on root directory / is not good practice.
Reference:
http://notes.rioastamal.net/2016/05/starting-ngrok-automatically-at-boot.html
After multiple failed attempts I have seem to come up with a working system. I first had to authorize the root user to use my ngrok account by doing the following:
sudo su
./ngrok authtoken {{Insert Your Auth Token Here}}
exit
Then, I created ngrokLauncher.sh and appLauncher.sh as shown.
ngrokLauncher.sh:
#!/bin/sh
# launcher.sh
cd /
./ngrok http -subdomain={{My Reserved Subdomain}} 5000 &
cd /
appLauncher.sh:
#!/bin/sh
# launcher.sh
cd /Storage/system/twilio/starter
python app.py &
cd /
Then, I modified the file permissions so they would be able to be run on startup sudo chmod 755 ngrokLauncher.sh && sudo chmod 755 appLauncher.sh. Lastly, I edited the Cron Jobs as follows:
Crontab:
# m h dom mon dow command
*/5 * * * * python /SKYNET/system/systemCheck.py
#reboot sh /Storage/ngrokLauncher.sh >/Storage/logs/cronlog 2>&1
#reboot sh /Storage/appLauncher.sh >/Storage/logs/cronlog 2>&1
Then after running sudo reboot, the system restarted and I received a response to my sms from the python app.
Related
I am trying to automate a bash script in Ubuntu. The script pings a server and then runs a python script if the packet is not received. The python script sends me a a notification when the ping is not returned. The script works when I run it manually, but it is not working when I schedule a cron job.
The bash script is named ping.sh.
#!/bin/bash
pingString=$(ping -c 1 google.com) # google is just and example, for my script I am using a server that intentionally does not return the packet.
msgRecieved="1 received, 0% packet loss"
msgLost="0 received, 100% packet loss"
if `echo ${pingString} | grep "${msgLost}" 1>/dev/null 2>&1`
then
python3 ping.py
fi
This is how I setup the cron job:
crontab -u username -e
* * * * * /bin/sh /home/username/Documents/ping.sh
I am confused because I set other dummy cron job for testing and it works fine. Example below:
* * * * * /bin/sh /home/username/Documents/test.sh
test.sh
#! /bin/bash
touch /home/username/Documents/ping_server/text.txt
The text.txt file is successfully created every minute.
Thanks for the suggestions. My problem was solved by
adding full path of the python script "ping.py" in the bash script
adding environment variables to crontab
I didn't know environment variables set in .bashrc are not loaded when running cron.
In Ubuntu it is possible to declare env variables before the jobs scheduled just like you would in bash.rc:
crontab -u username -e
ENV_VAR1=variable1
* * * * * /bin/sh /home/username/Documents/ping.sh
I created a python program, "test.py" and have saved it under /home/pi/. When I go to run it in the terminal using "python3 /home/pi/test.py" it runs properly and speaks "hello world". The code is shown below.
import os
import alsaaudio
m = alsaaudio.Mixer()
current_volume = m.getvolume()
m.setvolume(35)
os.system("espeak 'Hello World!'")
I want this program to start whenever my raspberry pi starts up. I tried to add this line in crontab but my raspberry pi doesn't execute the command. Does anyone know why my program won't execute?
#reboot python3 /home/pi/test.py
Here is an image of the syslog
can you try adding the full path to python3:
#reboot /usr/bin/python3 /home/pi/test.py
Also, regarding wanting to run the code on when the device boots - you can run your code as a service.
To do so create a .service file under /etc/systemd/system (for example my-code.service)
Enter the following inside the file
[Unit]
Description=My python service
After=network.target
[Service]
ExecStart=/usr/bin/python3 -u test.py
WorkingDirectory=/home/pi
[Install]
WantedBy=multi-user.target
Finally enable the service (in order for it to run on boot)
sudo systemctl enable my-code
If you want to run it independently you can also run
sudo systemctl start my-code
I'm trying to run a script automatic when booting Raspberry with DietPi.
My script starts a Python3 programm which then at the end starts an external program MP4Box which merges 2 video files to a mp4 in a folder in my lighttp webserver.
When I start the script manually everything works. But when the script starts automatically on boot, when it comes to the external program MP4Box, I get an error:
Cannot open destination file /var/www/Videos/20201222_151210.mp4: I/O Error
Script starting my pythons is "startcam" - which lies in the folder /var/lib/dietpi/postboot.d
#!/bin/sh -e
# Autostart RaspiCam
cd /home/dietpi
rm -f trigger/*
python3 -u record_v0.1.py > record.log 2>&1 &
python3 -u motioninterrupt.py > motion.log 2>&1 &
the readme.txt in postboot.d says:
# /var/lib/dietpi/postboot.d is implemented by DietPi and allows to run scripts at the end of the boot process:
# - /etc/systemd/system/dietpi-postboot.service => /boot/dietpi/postboot => /var/lib/dietpi/postboot.d/*
# There are nearly no restrictions about file names and permissions:
# - All files (besides this "readme.txt" and dot files ".filename") are executed as root user.
# - Execute permissions are automatically added.
# NB: This delays the login prompt by the time the script takes, hence it must not be used for long-term processes, but only for oneshot tasks.
So it should also start my script with root priviledges. And that is the (part of the) Script "record_v0.1.py" that throws the error:
import os
os.system('MP4Box -fps 15 -cat /home/dietpi/b-file001.h264 -cat /home/dietpi/a-file001.h264 -new /var/www/Videos/file001.mp4 -tmp ~ -quiet')
When I start the python programs manually (logged in as root) with:
/var/lib/dietpi/postboot.d/startcam
everythin is OK and instead of the error I get the message:
Appending file /home/dietpi/Videos/b-20201222_153124.h264
No suitable destination track found - creating new one (type vide)
Appending file /home/dietpi/Videos/a-20201222_153124.h264
Saving /var/www/Videos/20201222_153124.mp4: 0.500 secs Interleaving
Thanks for every hint
Contrary to the description, the scripts in postboot.d are not excuted as root. So I changed my script to:
#!/bin/sh -e
# Autostart RaspiCam
cd /home/dietpi
rm -f trigger/*
sudo python3 -u record_v0.1.py > record.log 2>&1 &
sudo python3 -u motioninterrupt.py > motion.log 2>&1 &
Now they are running as root and everything works as wanted.
I am trying to setup a crontab to run 6 python data scrapers. I am tired of having to restart them manually when one of them fails. When running the following:
> ps -ef | grep python
ubuntu 31537 1 0 13:09 ? 00:00:03 python /home/ubuntu/scrapers/datascraper1.py
etc... I get a list of the datascrapers 1-6 all in the same folder.
I edited my crontab like this:
sudo crontab -e
# m h dom mon dow command
* * * * * pgrep -f /home/ubuntu/scrapers/datascraper1.py || python /home/ubuntu/scrapers/datascraper1.py > test.out
Then I hit control+X to exit and hit yes to save as /tmp/crontab.M6sSxL/crontab .
However it does not work in restarting or even starting datascraper1.py whether I kill the process manually or if the process fails on its own. Next, I tried reloading cron but it still didn't work:
sudo cron reload
Finally I tried removing nohup from the cron statement and that also did not work.
How can I check if a cron.allow or cron.deny file exists?
Also, do I need to add a username before pgrep? I am also not sure what the "> test.out" is doing at the end of the cron statement.
After running
grep CRON /var/log/syslog
to check to see if cron ran at all, I get this output:
ubuntu#ip-172-31-29-12:~$ grep CRON /var/log/syslog
Jan 5 07:01:01 ip-172-31-29-12 CRON[31101]: (root) CMD (pgrep -f datascraper1.py ||
python /home/ubuntu/scrapers/datascraper1.py > test.out)
Jan 5 07:01:01 ip-172-31-29-12 CRON[31100]: (CRON) info (No MTA installed, discarding output)
Jan 5 07:17:01 ip-172-31-29-12 CRON[31115]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Jan 5 08:01:01 ip-172-31-29-12 CRON[31140]: (root) CMD (pgrep -f datascraper1.py || python /home/ubuntu/scrapers/datascraper1.py > test.out)
Since there is evidence of Cron executing the command, there must be something wrong with this command, (note: I added the path to python):
pgrep -f datascraper1.py || /usr/bin/python /home/ubuntu/scrapers/datascraper1.py > test.out
Which is supposed to check to see if datascaper1.py is running, if not then restart it.
Since Cron is literally executing this statement:
(root) CMD (pgrep -f datascraper1.py || python /home/ubuntu/scrapers/datascraper1.py > test.out)
aka
root pgrep -f datascraper1.py
Running the above root command gives me:
The program 'root' is currently not installed. You can install it by typing:
sudo apt-get install root-system-bin
Is there a problem with Cron running commands from root?
Thanks for your help.
First of all, you need to see if cron is working at all.
Add this to your cron file (and ideally delete the python statement for now, to have a clear state)
* * * * * echo `date` >>/home/your_username/hello_cron
This will output the date in the file "hello_cron" every minute. Try this, and if this works, ie you see output every minute, write here and we can troubleshoot further.
You can also look in your system logs to see if cron has ran your command, like so:
grep CRON /var/log/syslog
Btw the >test.out part would redirect the output of the python program to the file test.out. I am not sure why you need the nohup part - this would let the python programs run even if you are logged out - is this what you want?
EDIT: After troubleshooting cron:
The message about no MTA installed means that cron is trying to send you an e-mail with the output of the job but cannot because you dont have an email programm installed:
Maybe this will fix it:
sudo apt-get install postfix
The line invoking the python program in cron is producing some output (an error) so it's in your best interests to see what happens. Look at this tutorial to see how to set your email address: http://www.cyberciti.biz/faq/linux-unix-crontab-change-mailto-settings/
Just in case the tutorial becomes unavailable:
MAILTO:youremail#example.com
You need to add python home to your path at the start of the job, however you have python set up. When you're running it yourself and you type python, it checks where you are, then one level down, then your $PATH. So, python home (where the python binary is) needs to be globally exported for the user that owns the cron (so, put it in a rc script in /etc/rc.d/) or, you need to append the python home to path at the start of the cron job. So,
export PATH=$PATH:<path to python>
Or, write the cron entry as
/usr/bin/python /home/ubuntu/etc/etc
to call it directly. It might not be /usr/bin, run the command
'which python'
to find out.
The 'No MTA' message means you are getting STDERR, which would normally get mailed to the user, but can't because you have no Mail Transfer Agent set up, like mailx, or mutt, so no mail for the user can get delivered from cron, so it is discarded. If you'd like STDERR to go into the log also, at the end, instead of
"command" > test.out
write
"command" 2>&1 > test.out
to redirect STDERR into STDOUT, then redirect both to test.out.
I am working with a django app called django-mailbox. The purpose of this is to import email messages via pop3 and other protocols and store them in a db. I want to do this at regular intervals via a chron. In the documentation http://django-mailbox.readthedocs.org/en/latest/topics/polling.html it states:
Using a cron job
You can easily consume incoming mail by running the management command named getmail (optionally with an argument of the name of the mailbox you’d like to get the mail for).:
python manage.py getmail
Now I can run this at the command line locally and it works but if this was deployed to an outside server which was only accessible by a URL how would this command be given?
If you are using a virtual env use the python binary from the virtualenv
* * * * * /path/to/virtualenv/bin/python /path/to/project/manage.py management_command
on the server machine:
$ sudo crontab -l
no crontab for root
$ sudo crontab -e
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/ed
2. /bin/nano <---- easiest
3. /usr/bin/vim.basic
4. /usr/bin/vim.tiny
Choose 1-4 [2]:
choose your preferred editor
then see http://en.wikipedia.org/wiki/Cron for how to schedule when will the command run, direct it to some .sh file on your machine, make sure you give full path as this is going to run in root user context.
the script the cron will run may look something like:
#!/bin/bash
cd /absolute/path/to/django/project
/usr/bin/python ./manage.py getmail