- How can I resolve a hostname to an IP address in a Bash script?
- 27 Answers 27
- How to get a hostname/domain name from an IP address in Linux
- Prerequisites
- Perform DNS Reverse lookup using dig command
- Perform DNS Reverse lookup using nslookup command
- Perform DNS Reverse lookup using the host command
- Conclusion
- About the author
- Karim Buzdar
How can I resolve a hostname to an IP address in a Bash script?
What’s the most concise way to resolve a hostname to an IP address in a Bash script? I’m using Arch Linux.
Shame that the getent
@0xC0000022L: The new shame is that that answer suggests getent hosts somehost , when running this while on somehost will produce an IPv6 address, which is different from how most other tools ( ping , ssh at least) resolve names, and breaks some things. Use the ahosts instead of hosts .
@j_random_hacker: who keeps you from requesting specifically IPv4 ( ahostsv4 ) or IPv6 ( ahostsv6 ) addresses? Personally I find nothing wrong with the unspecific request returning IPv6. Your code should be prepared. IPv6 has been out there for more than 20 years now.
@0xC0000022L: Nobody «keeps me» from doing that, but the answer specifically suggests hosts , and so far 4 people have upvoted vinc17’s comment expressing the pain caused by «suddenly IPv6». Being prepared for IPv6 is not always the issue: many programs need a way to determine whether two names/addresses refer to the same host. They can either use simple string matching, or they must know a lot about the network to find the «true» answer. The latter is a minefield, so many 3rd-party programs and systems — that I have no control over — use the former.
27 Answers 27
You can use getent , which comes with glibc (so you almost certainly have it on Linux). This resolves using gethostbyaddr/gethostbyname2, and so also will check /etc/hosts /NIS/etc:
getent hosts unix.stackexchange.com | awk '< print $1 >'
Or, as Heinzi said below, you can use dig with the +short argument (queries DNS servers directly, does not look at /etc/hosts /NSS/etc) :
dig +short unix.stackexchange.com
If dig +short is unavailable, any one of the following should work. All of these query DNS directly and ignore other means of resolution:
host unix.stackexchange.com | awk '/has address/ < print $4 >' nslookup unix.stackexchange.com | awk '/^Address: / < print $2 >' dig unix.stackexchange.com | awk '/^;; ANSWER SECTION:$/ < getline ; print $5 >'
If you want to only print one IP, then add the exit command to awk ‘s workflow.
dig +short unix.stackexchange.com | awk '< print ; exit >' getent hosts unix.stackexchange.com | awk '< print $1 ; exit >' host unix.stackexchange.com | awk '/has address/ < print $4 ; exit >' nslookup unix.stackexchange.com | awk '/^Address: / < print $2 ; exit >' dig unix.stackexchange.com | awk '/^;; ANSWER SECTION:$/ < getline ; print $5 ; exit >'
By default, using dig only works with ipv4, where host gives both ipv4 and ipv6 answers. This might be unexpected. You can try host www.google.com , dig +short www.google.com , host ipv6.google.com , dig +short ipv6.google.com , host www.facebook.com , dig +short www.facebook.com .
Sometimes, host can be timed out and returns nothing. For some domains, dig +short may return domain alias in the first line. So, to ensure the output is an IPv4 address, use dig +short example.com | grep -Eo ‘[0-9\.]<7,15>‘ | head -1 .7,15>
Using getent hosts
Worth mentioning: host, dig and nslookup seems to directly talk to the servers listed in resolv.conf, whereas «getent hosts» respect both the local hosts file and library-level caching (such as nscd) if enabled.
With host from the dnsutils package:
$ host unix.stackexchange.com unix.stackexchange.com has address 64.34.119.12
(Corrected package name according to the comments. As a note other distributions have host in different packages: Debian/Ubuntu bind9-host, openSUSE bind-utils, Frugalware bind.)
Be aware that host sometimes returns multi-line output (in the case of redirects), you’ll want host unix.stackexchange.com | tail -n1 if you just want the line with the IP address.
There are multiple versions of «host» with different output formats. E.g. most systems seem to have the BIND9 version, but my Ubuntu 10.04 LTS server has some completely different version somehow..
if you don’t have host or dig installed you can use ping instead which is always available: ping unix.stackexchange.com -c 1 -q 2>&1 | grep -Po «(\d<1,3>\.)\d<1,3>» this does not need any extra packages install on most Unix/Linux matchines.1,3>
This answer deserves a serious downvote. host is a DNS tool (similar to nslookup ) so it only looks up hosts in DNS, not in e.g. /etc/hosts . So it is NOT an answer to OP’s question.
I have a tool on my machine that seems to do the job. The man page shows it seems to come with mysql. Here is how you could use it:
resolveip -s unix.stackexchange.com 64.34.119.12
The return value of this tool is different from 0 if the hostname cannot be resolved :
resolveip -s unix.stackexchange.coma resolveip: Unable to find hostid for 'unix.stackexchange.coma': host not found exit 2
UPDATE On fedora, it comes with mysql-server :
yum provides "*/resolveip" mysql-server-5.5.10-2.fc15.x86_64 : The MySQL server and related files Dépôt : fedora Correspondance depuis : Nom de fichier : /usr/bin/resolveip
I guess it would create a strange dependency for your script.
This seems to be the only solution on here that uses the OS’s build in resolver — so works for /etc/hosts as well as DNS.
getent , as detailed in the other answer, also looks at /etc/hosts, and comes with glibc, so has no dependencies on a Linux system.
I would not use resolveip since you create a dependency on another package. getent is installed by default. host, nslookup, and dig are all in optional packages. Definitely use getent in a script.
The following command using dig allows you to read the result directly without any sed/awk/etc. magic:
$ dig +short unix.stackexchange.com 64.34.119.12
dig is also included in the dnsutils package.
Note: dig has a return value of 0 , even if the name could not be resolved. Thus, you’d need to check if the output is empty instead of checking the return value:
hostname=unix.stackexchange.com ip=`dig +short $hostname` if [ -n "$ip" ]; then echo IP: $ip else echo Could not resolve hostname. fi
Note 2: If a hostname has multiple IP addresses (try debian.org , for example), all of them will be returned. This «problem» affects all of the tools mentioned in this question so far:
Note that if a domain has a CNAME entry its domain may be printed in the first line instead of an IP address.
getent hosts unix.stackexchange.com | cut -d' ' -f1
@ceving: On Solaris you might have to run cut without -d (defaults to \t as delimiter ). On Linux it’s spaces, thus the line above works.
The solutions given so far mostly work in the simpler case: the hostname directly resolves to a single IPv4 address. This might be the only case where you need to resolve hostnames, but if not, below is a discussion on some cases that you might need to handle.
Chris Down and Heinzi briefly discussed the case where the hostname resolves to more than one IP addresses. In this case (and others below), basic scripting under the assumption that a hostname directly resolves to a single IP address may break. Below, an example with a hostname resolving to more than a single IP address:
$ host www.l.google.com www.l.google.com has address 209.85.148.147 www.l.google.com has address 209.85.148.103 www.l.google.com has address 209.85.148.99 www.l.google.com has address 209.85.148.106 www.l.google.com has address 209.85.148.105 www.l.google.com has address 209.85.148.104
But what is www.l.google.com ? This is where the alias case needs to be introduced. Let’s check the example below:
$ host www.google.com www.google.com is an alias for www.l.google.com. www.l.google.com has address 74.125.39.103 www.l.google.com has address 74.125.39.147 www.l.google.com has address 74.125.39.105 www.l.google.com has address 74.125.39.99 www.l.google.com has address 74.125.39.106 www.l.google.com has address 74.125.39.104
So www.google.com does not directly resolve to IP addresses, but to an alias that itself resolves to multiple IP addresses. For more information on aliases, check here. Of course, the case where an alias has a single IP address is possible, as shown below:
$ host g.www.ms.akadns.net g.www.ms.akadns.net is an alias for lb1.www.ms.akadns.net. lb1.www.ms.akadns.net has address 207.46.19.190
But can aliases be chained? The answer is yes:
$ host www.microsoft.com www.microsoft.com is an alias for toggle.www.ms.akadns.net. toggle.www.ms.akadns.net is an alias for g.www.ms.akadns.net. g.www.ms.akadns.net is an alias for lb1.www.ms.akadns.net. lb1.www.ms.akadns.net has address 207.46.19.254 $ host www.google.fr www.google.fr is an alias for www.google.com. www.google.com is an alias for www.l.google.com. www.l.google.com has address 74.125.39.147 www.l.google.com has address 74.125.39.103 www.l.google.com has address 74.125.39.99 www.l.google.com has address 74.125.39.106 www.l.google.com has address 74.125.39.104 www.l.google.com has address 74.125.39.105
I did not find any example where a hostname resolves to an alias that does not resolve to an IP address, but I think the case might occur.
More than multiple IP addresses and aliases, is there some other special cases. what about IPv6? You could try:
$ host ipv6.google.com ipv6.google.com is an alias for ipv6.l.google.com. ipv6.l.google.com has IPv6 address 2a00:1450:8007::68
Where the hostname ipv6.google.com is an IPv6-only hostname. What about dual-stack hostnames:
$ host www.facebook.com www.facebook.com has address 66.220.153.15 www.facebook.com has IPv6 address 2620:0:1c08:4000:face:b00c::
Again about IPv6, if your host is IPv4 only, you can still resolve IPv6 addresses (tested on a IPv4 only WinXP and with ipv6.google.com, you could try it on Linux). In this case, the resolution succeeds, but a ping fails with an unknown host error message. This might be a case where your scripting fails.
I hope those remarks were useful.
How to get a hostname/domain name from an IP address in Linux
One of the questions that many Linux users ask is how they can retrieve a system’s hostname using its IP address. It may seem an uphill task, but in the real sense, it’s quite easy. Essentially, this is known as the reverse DNS lookup. Reverse DNS lookup queries an IP address to retrieve the hostname or domain of the server. The exact opposite is the Forward DNS lookup which maps the domain name to the IP address.
In this short guide, we have explored a few ways to performs Reverse DNS lookup and get a domain name from an IP address. For demonstration purposes, I have used Ubuntu 20.04.
Prerequisites
Before you roll up your sleeves, ensure that your remote host has an A record which is a DNS entry that points or maps a domain name to an IP address
Perform DNS Reverse lookup using dig command
Dig command is a flexible and powerful tool that is used for querying or probing DNS records. It’s an acronym for domain information groper and allows you to retrieve a wide array of DNS information such as A, CNAME, MX, and SOA records.
Perform DNS Reverse lookup using nslookup command
A nslookup command is a troubleshooting tool that features highly in a sysadmin’s armory. It’s a versatile tool that performs all DNS record querying such as CNAME, A, MX, and reverses or PTR records.
To retrieve a domain name from an IP address, use the command syntax:
Perform DNS Reverse lookup using the host command
Similarly, you can use the host command to obtain a hostname or domain name from an IP address using the syntax as shown.
For example, to check the domain name for the IP 5.9.235.235, execute the command:
Just like the Nslookup command, you can also use the host command with hostnames or IP addresses.
Conclusion
The few examples that we have just elaborated are a sure way of helping you obtain the domain name from an IP address. Usually, the reverse DNS lookup is trivial and not as crucial as the forward lookup, which maps domain names to IP addresses. Your feedback or contribution will be highly welcomed.
About the author
Karim Buzdar
Karim Buzdar holds a degree in telecommunication engineering and holds several sysadmin certifications. As an IT engineer and technical author, he writes for various web sites. He blogs at LinuxWays.