Ubuntu – Bash always evaluate Regex as true

bashregexscripts

In a script, there's these lines

#!/bin/bash

...

if ! [[ $SCREEN_NAME =~ ^[a-zA-Z0-9_.-]+$ ]]; then
  echo "The Server title contains invalid symbole. Only a-z A-Z 0-9 - _ . are allowed"
  exit 1;
fi

The problem is that, whatever value $SCREEN_NAME is set to, the script always exit with that message. I have tried reading regular expressions with Bash, and I see nothing wrong with it. What am I missing?

Update

Following comments and answers, I echoed $SCREEN_NAME, and nothing seemed wrong… until I did

echo "*$SCREEN_NAME*"

and saw that the second asterisk was put on a new line. Here's how $SCREEN_NAME is set :

SCREEN_NAME=$(grep -i 'server_screen_title' server.properties  | cut -f2 -d'=')

The value is read from the INI like config file. The interesting line is

server_screen_title=Test-Server

And I believe the value holds the terminating character \n. Thus the test fails. I've read man for cut, but I'm not sure how to fix this, nor if I'm right on this one.

Best Answer

I was too quick on this one, your test works. I suspect you somehow have set $SCREEN_NAME either globally or previously in the script as a string containing an illegal character.

^[a-zA-Z0-9_.-]+$ matches a non-NULL string containing only the allowed characters, so if $SCREEN_NAME is a non-NULL string containing only the allowed characters, $SCREEN_NAME =~ ^[a-zA-Z0-9_.-]+$'s value is 0.

! inverts its value, so if $SCREEN_NAME is a non-NULL string containing only the allowed characters, ! [[ $SCREEN_NAME =~ ^[a-zA-Z0-9_.-]+$ ]]'s value is 1.

So the condition is ok.

Run echo $SCREEN_NAME in both bash and your script and check whether the actual output matches what's expected.

Edit: To remove the trailing carriage return, one solution is to pipe grep's output to tr before cut:

SCREEN_NAME=$(grep -i 'server_screen_title' server.properties | tr -d '\r' | cut -f2 -d'=')
Related Question