The dig +short command (such as described in "dig show only answer") is great for batch processing names into IP addresses. It does a simple job and does it well.

Unfortunately when there's a CNAME even +short isn't short enough. For example:

$ dig +short docs.sbonds.org

I've tried +noall but it doesn't seem like it changes the behavior of +short. I've also tried specifying -t a just to ensure it didn't think I meant an A record or CNAME, but that (unsurprisingly) changes nothing.

$ dig +noall +short docs.sbonds.org

I'm using RedHat 7's dig:

# dig -v
DiG 9.9.4-RedHat-9.9.4-73.el7_6

I can filter out the CNAMEs with trusty grep, but it seems like dig should have some way to give "Just the IP, ma'am."

What is that way?


2 Answers 2


dig is a troubleshooting tool, so it sends DNS queries and receives DNS answers and as Andreas said the answer is both CNAME and A records, as designed. Your wish is to give "Just the IP, ma'am.", so that is not a DNS troubleshooting, it is "just" the resolution, for which dig is too much.


nslookup is inferior to dig but will still give you too much:

$ nslookup docs.sbonds.org

Non-authoritative answer:
docs.sbonds.org canonical name = ghs.google.com.
Name:   ghs.google.com


host is simpler but will still return "too much" for you (but note that it returns also the IPv6 address which is good):

$ host docs.sbonds.org
docs.sbonds.org is an alias for ghs.google.com.
ghs.google.com has address
ghs.google.com has IPv6 address 2607:f8b0:4004:815::2013


Depending on your Unix system, getent can be used. Note however that this may or may not do a DNS query because you configure in /etc/nsswitch.conf the source of data per service, and for hosts it will probably be a mix of both files (which is the venerable /etc/hosts) and the DNS.

$ getent hosts docs.sbonds.org
2607:f8b0:4007:801::2013 ghs.google.com docs.sbonds.org

Observe also that on a proper Unix setup it will favor IPv6 over IPv4 so that may be a problem for you (this should depend on the configuration in /etc/gai.conf)

In fact hosts does not honor /etc/gai.conf, you need to use ahosts instead, which will use getaddrinfo and hence gai.conf. Observe that you get a list (whose order depends on gai.conf configuration):

$ getent ahosts docs.sbonds.org   STREAM ghs.google.com   DGRAM   RAW
2607:f8b0:4007:801::2013 STREAM
2607:f8b0:4007:801::2013 DGRAM
2607:f8b0:4007:801::2013 RAW


If you are allowed to write a simple script, you have many solutions, like:

$ perl -MSocket -E 'say inet_ntoa(inet_aton("docs.sbonds.org"))'


Or use any DOH (DNS over HTTPS) endpoint (or similar) with any HTTP client. Examples:

$ curl --silent 'https://dns.google.com/resolve?name=docs.sbonds.org&type=A' | jq -c '.Answer[] | select(.type == 1) | .data'

$ curl --silent -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=docs.sbonds.org&type=A' | jq -c '.Answer[] | select(.type == 1) | .data'


Systemd has its own resolver application:

$ systemd-resolve docs.sbonds.org

-- Information acquired via protocol DNS in 239.1ms.
-- Data is authenticated: no

You still need to parse it in some way, but it does give the direct final IP addresses (there is a flag when you invoke it to make it not follow CNAME records for whatever use cases that need that)

  • "Write a simple script" is where I've always ended up before. It seemed like there must be a better way, but it looks like there is not. May 2, 2019 at 0:39
  • 1
    @SteveBonds see my update with a DOH case (similar to) May 2, 2019 at 0:59
  • You have no idea how much I wish "jq" was more widely installed. Nonetheless, that was an excellent addition to the solution! May 2, 2019 at 13:50
  • Just in case this helps, this is what I end up doing: dig +noall +answer host.example.com | awk '/ IN A\t/ { print $5 }'
    – dossy
    Apr 28 at 21:18
  • @dossy Your solution doesn't work (because it can be a space, not a tab after A depending on lots of things). Try with www.icann.org which is a CNAME. Parsing dig output is never a good idea and will yield a ton of edge cases. Apr 28 at 22:53

Both the CNAME and the corresponding A (or whatever type you asked for) belong to the answer-section. As such there is no dig option (at least not in RHEL7's dig) that could filter out the CNAME response.

I think you will have to rely on dig +short [...] | grep -v '\.$' to remove the CNAME responses.

  • 2
    Or dig +short ... | tail -1 May 1, 2019 at 23:14
  • 5
    not exactly. |tail -1 will show the last line. If there is more than one address in the RRset the CNAME points to this will give the wrong result. May 2, 2019 at 18:14
  • 1
    I agree but the user request could be understood as the IP, singular, not all :-). Indeed, whatever filtering is applied can have edge cases (filtering on end dot can fail if remote nameserver is broken in some way, like returning IP addresses there too; not supposed to happen but in DNS world everything can happen) May 2, 2019 at 18:36

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.