How can I resolve a hostname to an IP address in a Bash script?
Solution 1
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 }'
Solution 2
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.)
Solution 3
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...
Solution 4
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:
Solution 5
getent hosts unix.stackexchange.com | cut -d' ' -f1
Related videos on Youtube
Eugene Yarmash
Updated on September 18, 2022Comments
-
Eugene Yarmash over 1 year
What's the most concise way to resolve a hostname to an IP address in a Bash script? I'm using Arch Linux.
-
0xC0000022L about 9 yearsShame that the
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
answer is somewhere down there near the bottom. It's the simplest, requires no extra packages and is easier to parse from a Bash script, too. -
j_random_hacker almost 6 years@0xC0000022L: The new shame is that that answer suggests
getent hosts somehost
, when running this while onsomehost
will produce an IPv6 address, which is different from how most other tools (ping
,ssh
at least) resolve names, and breaks some things. Use theahosts
instead ofhosts
. -
0xC0000022L almost 6 years@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.
-
-
jfg956 over 12 yearsBy 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
. -
Gavin Brock almost 12 yearsSee the resolveip entry below if you need to resolve something not in DNS (e.g. /etc/hosts)
-
Gavin Brock almost 12 yearsThis 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.
-
ManiacZX over 11 yearsThe use of ping is what I needed as I need the value from the hosts file but the sed pattern parsing correctly but this worked ping -q -c 1 -t 1 your_host_here | grep PING | sed -e "s/^[^(]*[(]//" | sed -e "s/[)].*$//"
-
Edward Coffey over 11 yearsBe aware that
host
sometimes returns multi-line output (in the case of redirects), you'll wanthost unix.stackexchange.com | tail -n1
if you just want the line with the IP address. -
Mihai Danila about 11 yearsWhat a great complement to the accepted answer, showing all the edge cases that one might want to deal with in scripting. My version
host
does not even state "has address" for my boxes. -
Antoine Pelisse over 10 yearsAlso note that you may want to use
dig +search
if you want to reproducehost
command more closely -
sorin about 10 yearsDIG does not work, if is a CNAME it will not return the IP.
-
ColinM almost 10 yearsThere 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..
-
Boynux almost 10 yearsif you don't have
host
ordig
installed you can use ping instead which is always available:ping unix.stackexchange.com -c 1 -q 2>&1 | grep -Po "(\d{1,3}\.){3}\d{1,3}"
this does not need any extra packages install on most Unix/Linux matchines. -
caiguanhao almost 10 yearsSometimes,
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, usedig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1
. -
Andor almost 10 yearsTo be clear,
getent hosts
isn't just a lookup in /etc/hosts - it's a full-on DNS-resolving call to gethostbyaddr(3), and it's very unlikely to fail in a case wheredig
will succeed. See the man page for getent. -
Sushant almost 10 years@Stuart is right — i've learned a great deal since writing that and oversimplified a powerful command.
getent
remains my favorite, although i also likedig +short
-
peterh over 9 yearsThis answer deserves a serious downvote.
host
is a DNS tool (similar tonslookup
) so it only looks up hosts in DNS, not in e.g./etc/hosts
. So it is NOT an answer to OP's question. -
Matt Friedman over 9 yearsTo resolve something on my home network like myhostname.local this works so for me this is the best answer.
-
0xC0000022L about 9 yearsAlso consider
ahosts
,ahostsv4
,ahostsv6
withgetent
. -
0xC0000022L about 9 years
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
works for declarations inside/etc/hosts
, too ... and it's the go-to-tool for all kinds of system databases (passwd, group, aliases, services). -
CMCDragonkai almost 9 yearsWhen I
dig
with anhttp
protocol added, it findsSOA
. When Idig
without thehttp
protocol, it comes with the A record. What does this mean? Why does dig change depending on http protocol? -
Shah Zain almost 9 yearsIn the case where
host.domain.com
is a CNAME record, I found thatdig +short host.domain.com
will return the referenced DNS name instead of the IP address, whereasgetent hosts host.domain.com
will always return the IP address. -
michaelbn over 8 yearsBy far the most simple one. And its avilable by default. Not like
host
that require install of thebindutils
-
tomwhipple about 8 yearsThere's a big difference between "ask the OS to resolve a host" and "run this program which will use its internal logic to query DNS". I'm fairly sure that nslookup & dig are in the latter category, though I don't know about 'host'. For example, what if the host is defined in /etc/hosts?
-
clerksx about 8 years@tomwhipple For the purposes of this question, the distinction seems not particularly important. However, I will separate this answer out to differentiate functions using the OS resolver vs. their own means.
-
maxschlepzig about 8 yearsSome context in what way that answer improves over the already existing ones would be great. Also, please indent commands by 4 spaces (cf. the markdown syntax).
-
ceving about 8 years
cut
will not for getent's, which use\t
to separate columns. This is the case on Solaris. -
user848106 about 8 years@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. -
Asfand Qazi about 8 years
getent
, as detailed in the other answer, also looks at /etc/hosts, and comes with glibc, so has no dependencies on a Linux system. -
jamshid almost 8 yearsThanks, other answers assume "dig +short" always returns a single ip address. They weren't accounting for CNAMEs.
-
Saustrup almost 7 yearsWorth 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.
-
luissquall over 6 years
dig +short unix.stackexchange.com | awk '/^[0-9]+\./ { print ; exit }'
considers CNAMEs. -
Wimateeka over 6 years
host
can also return stale IP data. -
pcworld about 6 yearsNote that if a domain has a CNAME entry its domain may be printed in the first line instead of an IP address.
-
Radon8472 over 5 yearsI love this solution, because it works without any extra tools.
-
Radon8472 over 5 yearsusing ping is good, because everybody has it, but you need to to filter the IP-Part from the outputs, if you like to use it in a script.
-
Radon8472 over 5 yearsthis works, but it requires that php is installed on your terminal
-
Fabian Schmengler over 5 yearscan be useful on a typical php docker container where "host", "dig" etc. are not available
-
iuridiniz almost 5 yearsI can resolv avahi-hosts by using getent method (only this method)
-
dotbit over 4 years60% chance of breakage before you get anywhere near a resolve.
-
dotbit over 4 years
perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null
is much cleaner. but no one but the two of us are using pörl , everyone else uses Pascal Script of course. -
Thomas Jensen over 4 years@dotbit could you elaborate? I've used this weekly since '17 and never had any issues.
-
dotbit over 4 years@Jensen but you're the only one ever, as always. The rest of us usually run into FAIL of one sort or the other, and always.
-
Slaven Rezic over 4 yearsActually I prefer to see the error messages if anything goes wrong.
Can't call method "addr" on an undefined value
isn't exactly the best error message, but may give a hint about the problem. -
Slaven Rezic over 4 yearsThe ruby version prints quotes around the IP address --- probably
print
should be used instead ofp
. -
dotbit over 4 yearsthx, @Slaven Rezic and feel free to upvote. then again, here at the bottom the script may be more visible actually... ;-)
-
Thomas Jensen over 4 years"as always" What do you mean by that? "The rest of us" Who's that? "run into FAIL" What specific issue are you seeing? I'm curious.
-
FelikZ over 4 years
python3 -c 'import socket; print(socket.gethostbyname("www.example.com"))'
-
Nate about 4 yearsYou can use
$(dig +short example.com | tail -1)
to only take the last line of output of the command (in my testing it has always been an IP address and never a hostname, but I think this shouldn't be relied upon). Going the other way, for more robust checking for IPv4 address, you can build upon luissquall's awk command. I'm aware I'm being a bit pedantic, but that one only checks the first character. This checks whole lines:awk '/^([0-9]{1,3}\.){3}[0-9]{1,3}$/ { print ; exit }
... Match 1 to 3 digits followed by a dot, all that three times, then 1 to 3 digits, with nothing else after. -
Michael Grant about 4 yearsI 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.
-
MaXi32 almost 4 yearsi like this answer but it doesn't return ipv6
-
Jesper Rønn-Jensen over 2 yearsawesome tip. As far as I can see this is the only one that also will work on my mac and my windows machines