Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using "watch" to run a function repeatedly in Bash?

This is my first Bash script. I have a WiFi issue with my Debian machine. I'm not here to ask about the cause, but rather how to put a band-aid on the issue with Bash. My WiFi will drop out at a random time, usually every 12-15 minutes. I use SSH on this server, and do not want to have to run ifdown wlan0 and ifup wlan0 (which reconnects the WiFi) manually from the physical server.

The function of this Bash script is to attempt to connect three times. If it fails three times, it will give up. Otherwise, every three seconds it will check whether or not my server is connected by attempting to ping Google.

#!/bin/bash

ATTEMPTS=1

function test_connection {
  ping -c 1 www.google.com
  local EXIT_CODE=$?
  if [ $EXIT_CODE -eq 0 ]
    then
      return true
    else
      return false
  fi
}
function reset_connection {
  ifdown wlan0
  ifup wlan0
  EXIT_CODE=$((EXIT_CODE+1))
}
function connection_test_loop {
  if [ $ATTEMPTS -ge  3 ]
    then
      echo CONNECTION FAILED TO INITIALIZE ... ATTEMPT $ATTEMPTS FAILED ... EXITING
      exit
  fi
  if ! [ test_connection ]
    then
      echo CONNECTION DROPPED ... ATTEMPTING TO RE-ESTABLISH CONNECTION ... ATTEMPT $ATTEMPTS
      reset_connection
  fi
}

test_connection
if [ $? ]
  then
    echo CONNECTION PRE-ESTABLISHED
    watch -n 3 connection_test_loop
  else
    echo CONNECTION FAILED TO INITIALIZE ... ATTEMPTING TO RESET CONNECTION ... ATTEMPT $ATTEMPTS
    reset_connection
    if [ $? ]
      then
        echo CONNECTION ESTABLISHED
        watch -n 3 connection_test_loop
      else
        echo CONNECTION FAILED TO INITIALIZE ... ATTEMPT $ATTEMPTS FAILED ... EXITING
        exit
    fi
fi

I've isolated the issue I'm having with this script. It lies in calling the connection_test_loop function with watch. I've been unable to find any information as to why this isn't performing as expected and running the function every three seconds.

like image 257
Allenph Avatar asked Jan 26 '16 02:01

Allenph


2 Answers

It's possible that watch is not aware of your connection_test_loop function. You can try adding an export below the test_connection to perhaps solve the issue:

test_connection
export -f connection_test_loop
...

↳ http://linuxcommand.org/lc3_man_pages/exporth.html

When calling watch, you may need this syntax:

watch -x bash -c connection_test_loop
like image 78
l'L'l Avatar answered Sep 29 '22 01:09

l'L'l


I have multiple aliases and functions that used to not work with watch until I created a function that wraps the watch command like this, inspired from @l'L'l accepted answer:

# fishshell
function watch
    command watch -n 0.2 -x fish -c "$argv"
end

# bash
function watch() {
    watch -n 0.2 -x bash -c "$@"
}

# zsh
watch() {
    watch -n 0.2 -x zsh -c "$@"

}

The only inconvenient I see here is that you can't pass more watch arguments if you want to, for sure me I added the -n 0.2 flag to make it refresh every 0.2 seconds, if you have other flags that you like to add you will need to add them here beforehand.

Personally I only use fishshell so I hope the others are not broken, don't hesitate to edit the answer to fix the commands!

Also as a bonus for the lazy that often use watch: alias w=watch

like image 28
Seraf Avatar answered Sep 29 '22 01:09

Seraf