0

I would like to check hostnames to make sure they follow the standard naming convention in Bash Shell.

Let say the hostname is ab-cde-01

wolf@linux:~$ h='ab-cde-01'
wolf@linux:~$ echo $h
ab-cde-01
wolf@linux:~$ 

I started by building if else loop and it's working just fine.

wolf@linux:~$ if [ $h = 'ab-cde-01' ]; then
> echo $h is a valid name
> else
> echo $h is an INVALID name
> fi
ab-cde-01 is a valid name
wolf@linux:~$ 

However, when I try to use regex to replace numbers with [0-9], I'm getting an invalid name.

wolf@linux:~$ if [ $h = 'ab-cde-0[0-9]' ]; then
> echo $h is a valid name
> else
> echo $h is an INVALID name
> fi
ab-cde-01 is an INVALID name
wolf@linux:~$ 

update 1: =~ operator

=~ operator used as suggested ...

wolf@linux:~$ if [ $h =~ 'ab-cde-0[0-9]' ]; then
> echo $h is a valid name
> else
> echo $h is an INVALID name
> fi
bash: [: =~: binary operator expected
ab-cde-01 is an INVALID name
wolf@linux:~$ 

update 2: double bracket

wolf@linux:~$ if [[ $h =~ 'ab-cde-0[0-9]' ]]; then
> echo $h is a valid name
> else
> echo $h is an INVALID name
> fi
ab-cde-01 is an INVALID name
wolf@linux:~$ 
  1. What's wrong in this code?
  2. How to fix it?
  3. Is this the right/most efficient way to check hostname against certain standard?

update 3: Actual answer for my own reference too

wolf@linux:~$ if [[ $h =~ ab-cde-0[0-9] ]]; then
> echo $h is a valid name
> else
> echo $h is an INVALID name
> fi
ab-cde-01 is a valid name
wolf@linux:~$ 

Lessons learned

  1. Use double bracket instead of single bracket
  2. No quote in regex
Wolf
  • 1,631

1 Answers1

3

Your final attempt is the closest, but still has a couple of issues.

Fundamentally, it's not working because you are quoting the regex. It needs to be like this:

MATCH='ab-cde-0[0-9]'
if [[ "$h" =~ $MATCH ]];then

But there's still an issue there, because you haven't anchored the regex (meaning it can match in the middle of a given string), so the above would still pass for h=foo-ab-cde07bar.

Anchoring is done like so:

MATCH='^ab-cde-0[0-9]$'
if [[ "$h" =~ $MATCH ]];then

But in this limited example, you don't even need to use regex, you can use glob matching instead. This should work for what you have presented:

MATCH='ab-cde-0[0-9]'
if [[ "$h" = $MATCH ]];then

NB: I have quoted the $h string in all examples, because this is good practice.

Edit: I've now defined the matchers as variables, per suggestion from ilkkachu

bxm
  • 4,855
  • 2
    best way around the regex quoting issue is to put the regex in a variable, and expand it without quotes, i.e. re='^ab-cde-0[0-9]$'; if [[ $h =~ $re ]]; then ... – ilkkachu Jul 09 '20 at 11:08
  • Thanks @bxm, it works on Linux, but the same code didn't work on Windows cygwin (invalid name). Any reason for that? – Wolf Jul 09 '20 at 11:23
  • @ilkkachu good point, thanks ... updated – bxm Jul 09 '20 at 11:38
  • 1
    @Wolf Hmm maybe some peculiarity with how cygwin is handling things. You could try my latest edit where the matchers are quoted. – bxm Jul 09 '20 at 11:39