Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

What's the most concise way to resolve a hostname to an IP address in a Bash script? I'm using Arch Linux.

share|improve this question
Shame 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. – 0xC0000022L Apr 29 at 22:15

16 Answers 16

up vote 124 down vote accepted

As Heinzi said below, perhaps the best way is to use dig with the +short argument:

dig +short

Or getent, which comes with glibc:

getent hosts | awk '{ print $1 }'

If +short is unavailable for some reason, any one of the following should work:

host | awk '/has address/ { print $4 }'
nslookup | awk '/^Address: / { print $2 }'
dig | 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 | awk '{ print ; exit }'
getent hosts | awk '{ print $1 ; exit }'
host | awk '/has address/ { print $4 ; exit }'
nslookup | awk '/^Address: / { print $2 ; exit }'
dig | awk '/^;; ANSWER SECTION:$/ { getline ; print $5 ; exit }'
share|improve this answer
+1 for showing how to solve the "more than one IP" issue. – Heinzi Sep 15 '11 at 18:56
+1 That toughs me a great example for awk as well – rahmanisback Sep 15 '11 at 23:12
+1 for using dig. host is nice, but it's also nice to have options. – alesplin Sep 21 '11 at 2:12
By default, using dig only works with ipv4, where host gives both ipv4 and ipv6 answers. This might be unexpected. You can try host, dig +short, host, dig +short, host, dig +short – jfgagne Sep 21 '11 at 15:21
+1 for using a real "scriptable" command (dig +short) which only ouputs the IP address without that chatty human output "X has address Y"... – Totor Mar 26 '13 at 22:43

With host from the dnsutils package:

$ host has address

(Corrected package name according to the comments. As a note other distributions have host is different packages: Ubuntu bind9-host, openSUSE bind-utils, Frugalware bind.)

share|improve this answer
Did you mean dnsutils? Anyway, host worked nice, thanks – eugene y Sep 15 '11 at 14:55
You're probably right. I have no Arch here to check. (Intended to append a comment later mentioning this, but the answer was already upvoted so I supposed I nailed it...) – manatwork Sep 15 '11 at 15:06
See the resolveip entry below if you need to resolve something not in DNS (e.g. /etc/hosts) – Gavin Brock Jul 2 '12 at 8:56
Be aware that host sometimes returns multi-line output (in the case of redirects), you'll want host | tail -n1 if you just want the line with the IP address. – Edward Coffey Jan 23 '13 at 5:04
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.. – ColinM May 22 '14 at 19:51

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

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...

share|improve this answer
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. – Gavin Brock Jul 2 '12 at 8:57
Great, just what I needed - something that pays attention to /etc/hosts. – Xiong Chiamiov Feb 23 '13 at 3:21

The following command using dig allows you to read the result directly without any sed/awk/etc. magic:

$ dig +short

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:

ip=`dig +short $hostname`

if [ -n "$ip" ]; then
    echo IP: $ip
    echo Could not resolve hostname.

Note 2: If a hostname has multiple IP addresses (try, for example), all of them will be returned. This "problem" affects all of the tools mentioned in this question so far:

share|improve this answer
getent hosts | cut -d' ' -f1
share|improve this answer
Also consider ahosts, ahostsv4, ahostsv6 with getent. – 0xC0000022L Apr 29 at 22:12

The solutions given so far mostly work in the simpler case: the hostname directly resolves to a single ip address. This might be the only case where you need to resolve hostnames, but if not, bellow is a discussion on some cases that you might need to handle.

Chris Down and Heinzi shortly discussed the case where the hostname resovles to more than one ip addresses. In this case (and others bellow), basic scripting under the assumption that a hostname directly resolves to a single ip address may break. Bellow an example with a hostname resolving to more than a single ip address:

$ host has address has address has address has address has address has address

But what is This is where the alias case need to be introduces. Lets check the example bellow:

$ host is an alias for has address has address has address has address has address has address

So does not directly resolve to ip addresses, but to an alias that itself resolves to a 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 bellow:

$ host is an alias for has address

But can aliases be chained ? The answer is yes:

$ host is an alias for is an alias for is an alias for has address

$ host is an alias for is an alias for has address has address has address has address has address has address

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 multiples ip addresses and aliases, is there some other special cases... what about ipv6 ? You could try:

$ host is an alias for has IPv6 address 2a00:1450:8007::68

Where the hostname is an ipv6 only hostname. What about dual stack hostnames:

$ host has address 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, 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 usefull.

share|improve this answer
What 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. – Mihai Danila Feb 15 '13 at 23:23

To avoid the problem with aliases and always get a single IP address ready for use:

python -c 'import socket; print socket.gethostbyname("")'
share|improve this answer
ping -q -c 1 -t 1 your_host_here | grep PING | sed -e "s/).*//" | sed -e "s/.*(//"

works without dependencies on other systems (and for hosts specified in /etc/hosts)

share|improve this answer
The 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/[)].*$//" – ManiacZX Jan 18 '13 at 19:23
To resolve something on my home network like myhostname.local this works so for me this is the best answer. – Matt Friedman Jan 24 at 2:59
May I suggest this also: ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1 – Matt Friedman Jan 24 at 3:08
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). – 0xC0000022L Apr 30 at 7:53

Simple but usefull:

  1. getent ahostsv4 | grep STREAM | head -n 1 | cut -d ' ' -f 1
  2. getent ahostsv6 | grep STREAM | head -n 1 | cut -d ' ' -f 1
  3. getent hosts | head -n 1 | cut -d ' ' -f 1

All commands will resolve an IP address if host still exist. If host points to CNAME it will also get the IP in that case.

The first command returns the resolved IPv4 address

The second command returns the resolved IPv6 address

The third command will return the owners preferred address what may IPv4 or IPv6 address.

share|improve this answer

You could use host:

# strips the IP
IP=$( host ${hostname} | sed -e "s/.*\ //" )

# checks for errors
if [ $? -ne 0 ] ; then
   echo "Error: cannot resolve ${hostname}" 1>&2
   exit 1;
share|improve this answer
I'm not sure, but my host does return an error code (1) for unknown domains, and it says: "Host asdf not found: 3(NXDOMAIN)". – phunehehe Sep 15 '11 at 15:10
Indeed it does, sorry. I'll update – Matteo Sep 15 '11 at 15:38
$HOSTNAME should be $hostname -- by convention, we capitalize environment variables (PAGER, EDITOR, SHELL, ...) and internal shell variables (BASH_VERSION, RANDOM, ...). All other variable names should contain at least one lowercase letter. This convention avoids accidentally overriding environmental and internal variables. – Chris Down Sep 15 '11 at 16:23
@Chris: thanks, edited – Matteo Sep 15 '11 at 17:46

Here is a slight variation of the ping approach that takes "unknown host" into account (by piping through stderr) and uses tr to avoid the use of sed regexps:

ping -c1 -t1 -W0 2>&1 | tr -d '():' | awk '/^PING/{print $3}'

In case it's important to capture the exit value, then the following will work (although less elegant):

ping -c1 -t1 -W0 &>/dev/null && ping -c1 -t1 -W0 2>&1 | tr -d '():' | awk '/^PING/{print $3}'
share|improve this answer

here's a Bash recipe I cooked up using other folk's answers — first tries /etc/hosts, then falls back to nslookup:

    local host="$1"
    if [ -z "$host" ]
        return 1
        local ip=$( getent hosts "$host" | awk '{print $1}' )
        if [ -z "$ip" ] 
            ip=$( dig +short "$host" )
            if [ -z "$ip" ]
                echo "unable to resolve '$host'" >&2 
                return 1
                echo "$ip"
                return 0
            echo "$ip"
            return 0
share|improve this answer
To 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 where dig will succeed. See the man page for getent. – Stuart P. Bentley Aug 3 '14 at 11:42
@Stuart is right — i've learned a great deal since writing that and oversimplified a powerful command. getent remains my favorite, although i also like dig +short – RubyTuesdayDONO Aug 3 '14 at 18:26

To complete Chris Down's answer, and address jfgagne comments about (possibly chained) aliases, here is a solution that :

  • takes into account multiple IPs
  • takes into account one or more aliases (CNAME)
  • does not query /etc/hosts file (in my case I didn't want it); to query it, dbernt's python solution is perfect)
  • does not use awk/sed

    dig +short  | grep -v "\.$" | head -n 1

Always returns the first IP address, or empty tring if not resolved. with version of dig :

    $ dig -v
    DiG 9.8.1-P1
share|improve this answer

Maybe not the most concise, but it seems to be robust and efficient:

# $(get_host_dns_short "")
# Outputs the IPv4 IP Address of a hostname, resolved by DNS. Returns 0 if DNS
# responded successfully; 1 otherwise. Will mask error output.
function get_host_dns_short()
        set -o pipefail

        host -4 -W1 -t A "$1" 2>/dev/null | awk '/has address/ { print $NF; exit }'
    ) && return 0 || return 1

This will output a single IPv4 IP, as well as return 1 in the event of failure, while masking stderr output.

You can use it like this:

GOOGLE_IP="$(get_host_dns_short "")"
if [[ $? -eq 0 ]]; then
    echo "Google's IP is ${GOOGLE_IP}."
    echo "Failed to resolve Google's IP."

Google's IP is

If you want an IPv6 address instead, just replace -4 with -6.

share|improve this answer
 php -r "echo gethostbyname('');"
share|improve this answer
nmap -sP|grep YOUR_HOSTNAME|sed -n 's/.*[(]\([0-9\.]*\)[)].*/\1/p'

was the solution I found without DNS server

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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