How to run cron job when network is up?
I have some anacron jobs which run daily. The scripts update local bzr and git repositories. Naturally these scripts need working network connections. I'm on a laptop and often wired and wireless internet do not come up fast enough. This causes my cron job to time out when pulling the repositories =(
So:
How to make sure the internet is up before running specific cron jobs? Or how to fail a job if there is no network, such that it is retried by anacron later again?
Solution 1:
I think you can use Upstart to help you there. Mind you, I haven't tested that code below works but something very similar should.
# /etc/init/update-repositories.conf - Update local repos
#
description "Update local repos"
# this will run the script section every time network is up
start on (net-device-up IFACE!=lo)
task
script
svn up && git fetch
# do some other useful stuff
end script
That pretty much it. You might want to add some code to check that it does not run very often. You might also want to add start update-repositories
to your crontab, it'll make sure your update will happen if you are on the net constantly for a prolonged period of time.
Solution 2:
I made a cron that did a ping test on a DNS server to ensure networking. Something like this:
ping 8.8.8.8 -c 1 -i .2 -t 60 > /dev/null 2>&1
ONLINE=$?
if [ ONLINE -eq 0 ]; then
#We're offline
else
#We're online
fi
Recently I've used something like this:
#!/bin/bash
function check_online
{
netcat -z -w 5 8.8.8.8 53 && echo 1 || echo 0
}
# Initial check to see if we are online
IS_ONLINE=check_online
# How many times we should check if we're online - this prevents infinite looping
MAX_CHECKS=5
# Initial starting value for checks
CHECKS=0
# Loop while we're not online.
while [ $IS_ONLINE -eq 0 ]; do
# We're offline. Sleep for a bit, then check again
sleep 10;
IS_ONLINE=check_online
CHECKS=$[ $CHECKS + 1 ]
if [ $CHECKS -gt $MAX_CHECKS ]; then
break
fi
done
if [ $IS_ONLINE -eq 0 ]; then
# We never were able to get online. Kill script.
exit 1
fi
# Now we enter our normal code here. The above was just for online checking
This isn't the MOST elegant - I'm not sure how else to check via a simple command or file on the system, but this has worked for me when needed.
Solution 3:
You can talk to NetworkManager to see whether you are connected or not:
$state = $(dbus-send --system --print-reply \
--dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager.state 2>/dev/null \
| awk '/uint32/{print $2}')
if [ $state = 3 ]; then
echo "Connected!"
else
echo "Not connected!"
fi
Solution 4:
Just to wrap up a couple of the options here into a single script:
#! /bin/bash
# This script checks that the interface is up, and that an internet connection is available
# It is based on code from http://askubuntu.com/questions/3299/how-to-run-cron-job-when-network-is-up
#
# Then it sleeps for a random number of seconds between 30 and 600.
# This is based on code from http://tldp.org/LDP/abs/html/randomvar.html
#
# Collated by @JonTheNiceGuy on 2015-10-15
function check_ipaddr
{
# Here we look for an IP(v4|v6) address when doing ip addr
# Note we're filtering out 127.0.0.1 and ::1/128 which are the "localhost" ip addresses
# I'm also removing fe80: which is the "link local" prefix
ip addr | \
grep -v 127.0.0.1 | \
grep -v '::1/128' | \
grep -v 'inet6 fe80:' | \
grep -E "inet [[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+|inet6" | \
wc -l
}
function check_google
{
netcat -z -w 5 8.8.8.8 53 && echo 1 || echo 0
}
until [ `check_ipaddr` -gt 1 ]; do
sleep 2
done
until [ `check_google` -eq 1 ]; do
sleep 2
done
sleep $((RANDOM%570+30))
I plan to maintain this script at https://gist.github.com/JonTheNiceGuy/5cf4a23c8f2f755a9ca4