1

I need to supply either '-name' or '-sname' when starting an Erlang VM depending on whether the given string is a fully qualified name (FQDN) or not. What would be the quickest and environment-independent way of validating that? I am more interested in using some bash command (like 'getent' or 'nslookup' or others) rather than a regex expression. Best if it works in Ubuntu, FreeBSD and Solaris without changes and can be used in bash's 'if' easily.

4
  • Pretty much any string can be a valid fqdn provided it has a dot in it or at the end, so a lookup is the only way to be certain.
    – Paul
    May 6, 2014 at 14:04
  • You mean nslookup? That's what I mean. I want to make a lookup to be certain. I am just not sure if 'nslookup' is the way to go or maybe 'host' instead or something else?
    – Greg
    May 6, 2014 at 14:06
  • it seems like it might be a better idea to target a python or perl method instead of shelling a utility. shells change all the time, but a system with python3 will always run the same method correctly, regardless of what platform its installed on, and how that platform is configured. May 6, 2014 at 15:00
  • I just need to use it in an existing bash script when starting an Erlang node. Adding dependency on Python or Perl would be an overkill in my opinion.
    – Greg
    May 6, 2014 at 16:45

6 Answers 6

1

Host seems to work:

jalderman@mba:/tmp$ cat test.sh
#!/bin/bash

for h in "bert" "ernie" "www.google.com"
do
    host $h 2>&1 > /dev/null
    if [ $? -eq 0 ]
    then
        echo "$h is a FQDN"
    else
        echo "$h is not a FQDN"
    fi
done

jalderman@mba:/tmp$ ./test.sh 
bert is not a FQDN
ernie is not a FQDN
www.google.com is a FQDN
1
  • Looks like host could be replaced with nslookup and the script would work pretty much the same. Thanks.
    – Greg
    May 7, 2014 at 10:13
2

Unfortunately, I can not comment, but this is in fact a comment to the accepted answer: The solution does not check if the provided argument is really a FQDN. Simple host names that can actually be resolved will also qualify (simplest example: "localhost"). So perhaps the title of the question should be changed accordingly, if the question is not for a fqdn but simply for a resolving name. To actually add to the solution: If a fqdn is really required, you could simply check for a dot in the given name, like this:

is_fqdn() {
  hostname=$1
  [[ $hostname == *"."* ]] || return 1
  host $hostname > /dev/null 2>&1 || return 1
}

This will still allow for "localhost.", but thats technically a fqdn, anyways.

4
  • Good point. This is definitely an improvement over the previous answer. This answer could be the accepted answer if only the previous answer didn't help me to resolve my problem earlier :)
    – Greg
    Mar 9, 2016 at 11:05
  • I like this answer also but should't it check for more than one "."? [[ $hostname == *"."*"."* ]]
    – johnnyB
    May 11, 2016 at 20:41
  • 1
    No. Ensuring a single dot is present makes sure no plain hostname is provided (except for the already mentioned "localhost.", which is technically the fqdn for localhost, as localhost does not belong to any domain (except for the root label ".")). Any string containing at least one dot is potentially a valid fqdn. The usage of the "host" command makes sure the string resolves to an ip address, which means it is actually a fqdn. May 17, 2016 at 8:30
  • I think this answer might not correct after few years coming back. localhost. is not FQDN but localhost.somestring is FQDN.
    – MaXi32
    Jul 3, 2021 at 4:07
0

The "ndots" option of hostname could be used to do it all in one command:

host -N 0 $hostname

This will not append domains listed in the search or domain directive in /etc/resolv.conf.

Update with an example:

Assume you have a variable "hostname" wich contains a string, you want to know, if the string is a FQDN. Using simple "host" it will try the string and if not found it will append the "search" and "domain" from "/etc/resolv.conf".

$ hostname=www
$ host $hostname
www.example.com has address 192.168.0.1
$ host -N 0 $hostname
Host www not found: 3(NXDOMAIN)
$ echo $?
1

Which means "www" is not a FQDN. If it was a FQDN, it should be found by "host".

Another update:

I use Linux, but assumed, that the "host" command is the same as on FreeBSD.

1
  • Doesn't seem to work on FreeBSD. Can you add an example output so that I know what to expect?
    – Greg
    Jun 12, 2017 at 22:30
0

I use this for validate a domain name.

#!/bin/bash
DOMAIN=example.com    
[ -z "$(dig +short "$DOMAIN")" ]  &&  echo "$DOMAIN could not be looked up"

To get dig:

  • Debian/Ubuntu - apt-get install dnsutils
  • CentOS    - yum install bind-utils
0

I find the use of /usr/bin/host to be too slow for my taste, and for my purposes I only need to know if the string contains a dot. See https://unix.stackexchange.com/questions/63361/test-if-a-string-has-a-period-in-it-with-bash

0

I like to combine these 2 things regex and host command. You can use both if you are not satisfied with regex returning false, then do another check with host command

is_valid() {
    data="$1"
    if grep -oP '(?=^.{4,253}$)(^(?:[a-zA-Z0-9](?:(?:[a-zA-Z0-9\-]){0,61}[a-zA-Z0-9])?\.)+([a-zA-Z]{2,}|xn--[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])$)' <<<"${data}" >/dev/null 2>&1; then
      return 0
      # do second check using host command if regex above detected as false and finally return either true or false based host command
    else
      host "${data}" >/dev/null 2>&1
      retval=$?
      return "${retval}"
    fi
}

if is_valid "example.com"; then
   echo "Valid!"
else
   echo "Not Valid!"
fi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.