문제

I've been banging my head on this one for a bit. Wanted to see what I'm doing wrong, and it's probably all me on this one. I'm pinging an IP, then when it goes down or up, it will send a notification. My issue is with getops. I'm using it to attempt to parse the email address and the ip. Neither of these are being parsed. How can I go about parsing my two variables using getopts I need to allow my script to run properly. Thank you in advance :)

#!/bin/bash
# Variable(s)
# --------
EMAIL_DOWN_SENT="0";
EMAIL_UP_SENT="0";
PING_FAILED="0";
PING_UP_AGAIN="0";

# FUNctions
# ---------
# 
# Echo a string value that is passed
echo_text() {
   echo -e >&2 "$@";
}

echo_help() {
echo_text "Usage: $(basename "$0") [-e] [EMAIL][-h] [-i] [IP]\n\nScript to ping ip address to see if it's up and send an alert on status changes.\n
        -e Enter email: user@domain.tld
        -h This help screen
        -i IP to ping";
   exit;
}

# Main body
# ---------
#
# Get command line options
# ------------------------
while getopts ":e:hi:" OPTIONS 
do
  case $OPTIONS in
     e) EMAIL=$OPTARGS ;;
  h|\?) echo_help ;;
     i) IP= $OPTARGS | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'; if [ "$?" != "0" ]; then echo_text "Please enter a valid IP"; exit 1; fi; ;;
     *) echo_text "$OPTARGS is invalid, try again";
        exit 1 ;;
  esac
  shift $((OPTIND-1))
done
echo_text "Your email is: $EMAIL";
echo_text "Your ip to ping is: $IP";

# Ping me
# -------
trap "echo You hit ctrl-c, now exiting..; exit" SIGINT
while :
do
   ping -i 2 -c 2 $IP > /dev/null
   if [ $? -ne 0 ]; then
      let PING_DOWN+=1
      echo_text "Down! Abandon all hope who enter here...";
      PING_FAILED="1";
      # If greater than 3 cycles send an email...
      if [[ $PING_DOWN -ge 3 && $EMAIL_DOWN_SENT -eq 0 ]]; then
         echo "$IP Down!"|mutt -s "Ping Failed!" $EMAIL;
         EMAIL_DOWN_SENT="1";
      fi
   else
      let PING_UP+=1
      echo_text "Up! Ahoy! Host alive!";
      # If greater than 3 cycles send an email...
      if [[ $PING_UP -ge 3 && $EMAIL_UP_SENT -eq 0 && $PING_FAILED -eq 1 ]]; then
         echo "$IP up!"|mutt -s "Ping succeeded!" $EMAIL;
         EMAIL_UP_SENT="1";
         PING_UP_AGAIN="1";
      fi
      # Reset checks
      if [ $PING_UP_AGAIN -eq 1 ]; then
         PING_FAILED="0";
         PING_UP="0";
         PING_DOWN="0";
         EMAIL_UP_SENT="0";
         EMAIL_DOWN_SENT="0";
      fi
   fi
done

if [ ! `echo "$OPTARG" | grep -qE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'` ]; then
    echo_text "Please enter a valid IP"
    exit 1
fi
IP="$OPTARG"
도움이 되었습니까?

해결책

There are two main things wrong in your script:

First, it's $OPTARG, not $OPTARGS.

Second,

IP= $OPTARGS | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}';

You cannot do that. Change the whole paragraph to something along the lines of

if ! echo "$OPTARG" | grep -qE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'; then
    echo_text "Please enter a valid IP"
    exit 1
fi
IP="$OPTARG"

It's also worth noting that, unless you are using an ancient bash, your shell should have a =~ operator (see here) that you can replace the external grep with:

When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex3)). The return value is 0 if the string matches the pattern, and 1 otherwise.

다른 팁

In addition to the problems Adrian Frühwirth pointed out, you need to move the shift command to after the loop. The way you've written it, it's removing the script's arguments while getopts is still parsing them, which will confuse things completely.

while getopts ":e:hi:" OPTIONS 
do
    ...
done
shift $((OPTIND-1))  # This must be after the "done"

Try to enclose $OPTARGS with "" :

e) EMAIL="$OPTARGS" ;;

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top