Linux сопоставить ip и имя

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

Читайте также:  Linux mount linux lvm

Using getent hosts is incorrect, as for instance it may give an IPv6 address while IPv6 doesn’t work. The correct solution is to use getent ahosts to try both IPv6 and IPv4 if needed.

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.

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.

Читайте также:  Сетевое имя компьютера linux

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.

Читайте также:  Чем отличаются друг от друга linux дистрибутивы

I hope those remarks were useful.

Источник

How to set a domain to ip address?

You can reach this IP address 2.186.116.46 (if my computer is online). I want to assign a domain to it so I wonder how is that possible when I have no DNS? I do own my domain which is «.com». My IP is static. Thanks

There are a lot of free DNS providers. If you don’t want to use them, you’ll need to edit the /etc/hosts file on each computer that uses the IP address.

It looks like you using Apache/2.4.7. So in short: 1st you have to acquire FQDN from some DNS provider. 2nd: you must setup a ServerName directive into your /etc/apache2/sites-available/your-virtualhost.conf file.

If this is just for your use, I highly recommend freedns.afraid.org. You can either use a custom domain that you get elsewhere, or you can take a subdomain of any of their thousands. The guy who runs it is also very friendly and has helped me with some of my DNS problems.

2 Answers 2

1. You need to acquire a domain name (or maybe just FQDN) from some DNS provider.

2. Once you have registered the domain name, you will gain access to an administrative panel (like this one shown below), where you will be able (via A records), to redirect the domain name (and all *. or certain sub domains / FQDNs) to your server’s IP address.

enter image description here

  • Please note that the provider’s administrative panel shall looks different, and the provider will give you exact instructions how to use it.
  • Sometimes the redirection can take up-to 24 hours. You can check if it’s successful by the command whois example.com .
  • If the server is behind NAT, you must setup port forwarding.

3. Edit your Virtual Host configuration file and add relevant ServerName and maybe ServerAlias directives. Let’s assume the configuration file is 000-default.conf that should look as this:

 ServerName example.com ServerAlias www.example.com localhost ServerAdmin webmaster@localhost DocumentRoot /var/www/html # etc . ErrorLog $/error.log CustomLog $/access.log combined 
  • This step can be omitted, but it is absolutely necessary when you have more than one Virtual Hosts.
  • Don’t forgot to:
sudo a2ensite 000-default.conf sudo systemctl reload apache2.service 

4. In addition for local needs:

    You can bind a FQDN to the loopback interface of the server. For this purpose, edit the file /etc/hosts in a way like this:

127.0.0.1 localhost example.com www.example.com 
77.77.77.70 example.com www.example.com 

Источник

Оцените статью
Adblock
detector