1

I have a useradd bash script which requests the user enter an e-mail address for the user being created. This is so the user receives his username/password in an e-mail when his/her account is created.

Currently this part of the code is very simple:

echo Enter the users e-mail address
read ADDRESS

What i'm finding is that sometimes when the operators run the script they are entereing blank information. How can I put a if statement in place that enforces they enter an e-mail address format.

I tried the following code but it doesn't work. The idea was to at least verify they are using the @ symbol.

if [[ $string != "@" ]] ; then
    echo You have entered an invalid e-mail address!
    exit 1
else
    # do something
fi
geekosaur
  • 59,309
  • 11
  • 123
  • 114
titzmgee
  • 11
  • 1
  • 3

4 Answers4

4

If you're just looking for something quick and dirty, this bash conditional expression will match something that has at least one char, an '@', at least one char, a dot, and at least one char.

[[ "$email" == ?*@?*.?* ]] 

Examples

$ [[ "a@b.c" == ?*@?*.?* ]] && echo Y || echo n
Y
$ [[ "foo@bar" == ?*@?*.?* ]] && echo Y || echo n
n

Actual email validation is gnarly (see here)

Community
  • 1
  • 1
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Thanks for the answers. I actually have what I need with this regex: if [[ "$ADDRESS" =~ "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$" ]] – titzmgee Jul 01 '11 at 23:57
2

!= tests for exact inequality: the string would have to be exactly @ with nothing else. Two ways to do the test you want are

case "$string" in
*@*)
    ;;
*)
    echo You have entered an invalid email address! >&2
    exit 1
    ;;
esac

or

if ! expr "$string" : '.*@' >/dev/null; then
    echo You have entered an invalid email address! >&2
    exit 1
fi

You need to redirect the result from expr because it will print the matched length. Note also that case uses shell globs, whereas expr uses POSIX basic regular expressions (so you can't use +, ?, etc.); and you need to quote the regex passed to expr so the shell doesn't expand it, but for case the whole point is to have the shell expand it.

I generally prefer the case one unless I actually need a regex.

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • Actuall, my bash manual says `==` and `!=` within `[[ ]]` are pattern matching operators. – glenn jackman Jun 29 '11 at 17:21
  • @glenn: Are you sure? That would break compatibility with POSIX pretty badly, and `bash` is supposed to be POSIX compatible. `=~` and `!~` are the pattern matching operators (and relatively new). – geekosaur Jun 29 '11 at 17:25
  • The way I read the man page, `=~` and `!~` are *regular expression* matching operators, and `==` and `!=` are *glob* (and extglob) matching operators. See the discussion of `[[...]]` in the [bash manual](http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs) – glenn jackman Jun 29 '11 at 18:20
  • Also, note the difference between `[[ "hello" == "hell?" ]]` and `[[ "hello" == hell? ]]` – glenn jackman Jun 29 '11 at 18:26
  • @glenn: So the `bash` maintainers finally jettisoned any pretense of [POSIX compatibility](http://pubs.opengroup.org/onlinepubs/009695399/utilities/test.html)? Lovely. (One could quibble about `=` vs. `==`, but `!=` tests for identical strings.) – geekosaur Jun 29 '11 at 18:26
0

You could e.g. use bash's =~ operator, e.g.:

if [[ $string =~ "@" ]] ; then
    # do something
else
    echo You have entered an invalid e-mail address!
    exit 1
fi
bmk
  • 13,849
  • 5
  • 37
  • 46
0

You can use glob-style patterns in if conditionals in bash:

if [[ $string != *"@"* ]] ; then
    echo You have entered an invalid e-mail address!
    exit 1
else
    # do something
fi

I'd go a step further and require at least one character at either side of the @:

if [[ $string != *?"@"?* ]] ; then
    echo You have entered an invalid e-mail address!
    exit 1
else
    : # do something
fi
thkala
  • 84,049
  • 23
  • 157
  • 201