44

In part of the script that I'm working on, I want to validate that the inputted IP address is in the correct format. I want to make a loop while the input format is NOT correct. The following works for a loop while the format IS correct.

while  [[  $range =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
      do

How can I turn this around to say DOES NOT fit the format. I was hoping !=~ would work, but I'm getting a syntax error.

1
  • 2
    Synner, one note of caution: while it is clear that you're writing an interactive script, the immense power of shell scripting comes from being able to do the same thing with the same script both interactively and in the batch mode. It will be definitely easier in the future (when you start using the script as a building block) to simply enter the options in the command line and return immediately with a non-zero exit code (and a message) if anything is wrong. Just my 2 cents... Mar 16, 2013 at 18:41

3 Answers 3

100

The solution is so simple, I'm sure you will all find it funny.

No need to get worked up about negation syntax details, just use until instead of while.

9

For comparison of string, one should use != instead of !=~.

From man bash

string1 != string2
          True if the strings are not equal.

As you are using a regular expression on the right, you indeed need =~. You can chose to negate the whole expression.

while  [[  !( $range =~ ^[0-9]{1,3]}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ) ]]

Example:

$ bash --version | head -n1
GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)
$ cat script
range='1'; while [[ !( $range =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ) ]]; do echo "$range NOT OK"; range+='.2'; sleep 1; done
echo "Finished"
$ bash script
1 NOT OK
1.2 NOT OK
1.2.2 NOT OK
Finished
$ 
6
  • Thanks for the quick responses. I've attempted that before posting, and it does not validate properly. It seems to need the ~ to work properly as well when validating that it DOES fit the format.
    – Synner
    Mar 16, 2013 at 18:45
  • @Synner Check the edit
    – Bernhard
    Mar 16, 2013 at 18:56
  • Not works with bash 4.2.42. pastebin.com/0vHh5MMB
    – manatwork
    Mar 17, 2013 at 14:51
  • 1
    @manatwork Try in a non-interactive shell.
    – Bernhard
    Mar 17, 2013 at 15:06
  • @manatwork See my edit
    – Bernhard
    Mar 17, 2013 at 15:40
1

Just put "!" before statement, like:

while ! [[  $range =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
do
   run-command
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .