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
Related
On Raspberry Pi 3B+ running on Raspberry Pi OS 64.
Trying to make a Python script executed every minute but don't work.
To edit crontab, I use :
sudo crontab -e
And put this line in file :
*/1 * * * * sudo /bin/python3 /home/pi/Documents/script_test01.py`
I also tried : */1 * * * * sudo python3 /home/pi/Documents/script_test01.py
Here my script, simply publish in a MQTT broker (script works by direct call in shell: python3 script_test01.py):
#!/usr/bin/env python3
import time
import paho.mqtt.client as mqtt
client_mqtt = mqtt.Client("Script-crontab")
client_mqtt.connect("localhost")
client_mqtt.publish("RandomTempValuesSimulator", "Hello !")
client_mqtt.disconnect()
exit()
I did a stop and start cron service with :
sudo systemctl stop cron.service
sudo systemctl start cron.service
Nothing more happened.
Make sure your script is executable. The interpreter is usually at /usr/bin/python3 (not /bin/python3) but you don't need that since you have the #! on top of your script.
Why are you editing root's crontab? Why not just your own? Check your /var/log/syslog files for any errors in the execution.
Solved.
When i did crontab -l, i've got no crontab for pi user.
Problem solved without "sudo" with command crontab -e and edit the blank crontab file openned and put this command : */1 * * * * /bin/python3 /home/pi/Documents/script_test01.py
This is how I configure crontab (by using crontab -e)
* * * * * /home/jeff/Desktop/scripts/job_pull_queue.sh >> /home/jeff/Desktop/scripts/log.txt
This is the content of /home/jeff/Desktop/scripts/job_pull_queue.sh
#!/bin/bash
echo "Running job_pull_queue.sh # $(date)"
cd /home/jeff/Documents/code/some_project
echo $(printenv)
/home/jeff/miniconda3/bin/python -m util.main
Now the problem is, when running ./job_pull_queue.sh in the terminal, it works, but I can tell from the log file that crontab never executes that last line /home/jeff/miniconda3/bin/python -m util.main (I can see the result from the previous echo in the log file, but not the python script itself), what happened? How do I fix it?
Update: here's the result from printenv when ran by crontab
SHELL=/bin/sh PWD=/home/jeff/Documents/code/some_project LOGNAME=jeff HOME=/home/jeff LANG=en_US.UTF-8 SHLVL=0 PATH=/usr/bin:/bin OLDPWD=/home/jeff _=/usr/bin/printenv
Ok...
My Python script reads several env variables from my user profile, and of course, these variables don't exist when crontab is running the script...
And I don't have detection/logging in place so I didn't know env variables are missing.
I have a shell script that sets up our crontab on AWS EMR.
The shell script is run as part of EMR steps setup.
However when it excecutes it is evaluating the date directly and not the text as is which is what I want as that cronjob will be run dynamically based on yesterday's date
My script crontab portion
crontab -l && echo "0 20 * * * python app.py --date=$(date -d "yesterday" +\%Y-\%m-\%d) >> app.log 2>&1") | crontab -
Pasted manually in emr it shows like original which is what I want but now I want to automate the cron setup
The EMR step scripts executes this shell script and evuluates the environment variable to the true value like so:
crontab -l && echo "0 20 * * * python app.py --date=2020-01-16 >> app.log 2>&1") | crontab -
This is not what I want as now my cron will only run this for that set date.
How can I make it so that the script's environment variable is not evaluated and kept as is format?
Replace the double-quotes with single-quotes to keep the $(date...) from being expanded when the echo is run.
I have a bash script that I'm using to execute a python file with a specific version of Python (3.6). The Bash script is currently located on my desktop (/home/pi/Desktop/go.sh)
#!/bin/bash
python3.6 /home/pi/scriptDir/myScript.py
Here is my crontab entry, when I do crontab -l (note, I've deleted my other jobs)
* * * * * bash /home/pi/Desktop/go.sh # JOB_ID_3
When I run this file using the command line or from the GUI it executes properly.
When I have crontab do it, nothing happens.
Both my python file and the bash script are executable. chmod +x
Is there something obvious I'm missing?
**my python script does depend on other files in the same script directory, could that be the issue?
Here's what got it working for me. I was not using the full path to my python install. Unless you log the bash file there's no indication that you have an issue.
This is my bash file now. echo's were just to determine that I was indeed running the bash file.
#!/bin/bash
echo started
/home/pi/Python-3.6.0/python home/pi/myScriptFolder/myScript.py
echo finished
To break down the line executing the script:
/home/pi/Python-3.6.0/python - is where python 3.6.0 is installed on my Pi, it could be different for you. home/pi/myScriptFolder/myScript.py is the script I want to run.
And here is my cron statement:
*/15 * * * * bash /home/pi/Desktop/go.sh > /home/pi/Desktop/clog.log 2>&1 -q -f
Breaking down this line:
*/15 * * * * is the cron time, in this case every 15 mins. bash /home/pi/Desktop/go.sh specifies to run a bash file and the directory of that file. > /home/pi/Desktop/clog.log 2>&1 -q -f this last section creates a log file named clog.log so you can see what's going on.
The key here was not just logging the go.sh bash file execution, but adding the 2>&1 -q -f to the end of the log request. Before I did that there was no indication of a problem, afterwards I was getting the python files error returned into the log file.
Cron jobs are surprisingly tricky. Aside from working directory ( which you'd have to set somewhere), you also need to handle environment setup ( $PATH, for example).
Start by redirecting your shell script's standard output and error to a log file so you can get feedback.
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.