Monday, January 10, 2011

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 this scripts need working network connections. I'm on a laptop and often wired and wireless internet do not come up fast enough. This results in my chron job to time out on 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?

From ubuntu Dima
  • What I do is create a shell script that does what you need, ie. checks for network connection and then fires off the updates. Then call the script from cron.

    From nixternal
  • To expand on nixternal, the fping binary is excellent for that. You can cook it up in one-liners as in

    $ fping -q yoo.mama && echo yes
    $ fping -q www.google.com && echo yes
    yes
    $ 
    

    As you see, yoo.mama does not like me but Google does. In crontab, you'd do something like

    5 5 * * *  root   fping -q google.com && /some/script/I/want --to --run
    
    aperson : That won't run the command later if the network is down. How could that be accomplished?
  • 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're online
    IS_ONLINE=check_online
    # How many times we should check if we're online - 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.

  • 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.

    From vava
  • 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
    

0 comments:

Post a Comment