Bash regex failing in case statement
<p>I'm working on a section of a script which accepts a network mask in either CIDR (<code>/##</code>or just <code>##</code>) or dotted-decimal (<code>###.###.###.###</code>) notation. Both end up being the dotted-decimal notation after conversion, but I want to give the flexibility to enter CIDR. My regexes don't seem to work, though:</p>

<p>All of my test code:</p>

<pre><code>function cidr2mask ()
{
   # Number of args to shift, 255..255, first non-255 byte, zeroes
   set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 &lt;&lt; (8 - ($1 % 8))) &amp; 255 )) 0 0 0
   [ $1 -gt 1 ] &amp;&amp; shift $1 || shift
   echo ${1-0}.${2-0}.${3-0}.${4-0}
}

function validate_netmask() {
   echo $1 |grep -E -q '^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)' &amp;&amp; echo "Valid netmask" || echo "Invalid netmask"
}

while [[ -z $mask ]]
do
  read -p "Enter the netmask in either CIDR or dotted notation: " mask
  echo "Netmask: $mask" #debugging
  case $mask in
    ^\/?[0-9][0-9]$)
      cidr=$(echo $mask |sed 's/^///')
      netmask=$(cidr2mask $cidr)
      validate_netmask $netmask
      break
      ;;
    ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)
      validate_netmask $mask
      break
      ;;
    *) echo "Invalid netmask"
      continue
      ;;
  esac
done
</code></pre>

<p>As I've said, the regexes don't appear to work. Everything is dropping to the default case statement:</p>

<pre><code>[user@centos7 bin]$ bash scratch.sh 
Enter the netmask in either CIDR or dotted notation: 24
Invalid netmask
[user@centos7 bin]$ bash scratch.sh 
Enter the netmask in either CIDR or dotted notation: /24
Invalid netmask
[user@centos7 bin]$ bash scratch.sh 
Enter the netmask in either CIDR or dotted notation: 255.255.255.0
Invalid netmask
</code></pre>

<p>I've tried different methods of reading the $mask variable into the <code>case</code> including <code>$mask</code>, <code>"$mask"</code>, and <code>${mask}</code>. I've also tried not escaping the <code>/</code> for the CIDR notation (<code>^/[0-9][0-9]</code>).</p>

<p>What am I doing wrong?</p>