Take the 2-minute tour ×
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.

The Linux host command returns:

hostA.domain.com has address xx.xxx.xxx.xx

How do I get just the IP address and put it in the $ipaddr variable?

open(FILE, "hostlist.txt") or die("Unable to open file");
@hostnames = <FILE>;
close(FILE);
foreach $hostname (@hostnames)
{
    $lookup = qx(host $hostname);
    $ipaddr = grep ip_address $lookup;  <---- need help here
    print $ipaddr;
}
share|improve this question
add comment

4 Answers

up vote 5 down vote accepted

Since you posted this on the Unix & Linux site, instead of StackOverflow, I'm wondering if something like this isn't what you're looking for:

cat hostlist.txt | xargs resolveip -s

This will only return one IP address though.

Some hostnames will have multiple IP addresses associated with them:

$ host www.google.com
www.google.com is an alias for www.l.google.com.
www.l.google.com has address 74.125.227.18
www.l.google.com has address 74.125.227.17
www.l.google.com has address 74.125.227.16
www.l.google.com has address 74.125.227.20
www.l.google.com has address 74.125.227.19

To get just the list of IPs, one way to do it is:

host <hostname> | grep "has address" | awk '{print $4}'

If you want to stick with Perl, using resolveip:

$ipaddr = qx(resolveip -s $hostname);

Or to get all of the IPs, without executing any shell commands:

use Socket;
@ipaddrs = map { inet_ntoa($_) } (gethostbyname($hostname))[4,];
share|improve this answer
    
Thanks everyone for your advice. –  user11496 Jan 4 '12 at 6:55
    
Note the , which makes it special to grab all the addresses :-) Example: @addresses = gethostbyname($name) or die "Can't resolve $name: $!\n"; @addresses = map { inet_ntoa($_) } @addresses[4 .. $#addresses]; # @addresses is a list of IP addresses ("208.201.239.48", "208.201.239.49") –  Nikhil Mulley Jan 17 '12 at 12:29
add comment

Why not just use dig +short?

share|improve this answer
add comment

I'd use something like:

(\d{1,3}\.){3}\d{1,3}

If you want something more exacting, then you'll probably have:

([012]?\d{1,2}\.){3}[012]?\d{1,2}

But even this is still somewhat loose. For example, it still allows '269.278.287.296' to falsely match.

But both match the standard 0.0.0.0 to 255.255.255.255.

share|improve this answer
    
\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?‌​[0-9][0-9]?)\b would fit for all the possible and valid ip address range. –  Nikhil Mulley Jan 14 '12 at 11:29
    
I also use search.cpan.org/~neely/Data-Validate-IP-0.14/lib/Data/Validate/… perl module to check if the IP address is IPV4 valid style. –  Nikhil Mulley Jan 14 '12 at 11:35
add comment

To add to @mkopala 's answer, if you have multiple hosts and you want to keep a track of them, build a hash, so that there is a easy reference of host to ip mapping.

Example:

#!/usr/bin/perl
use Socket;
@hostnames = ('www.google.com', 'www.yahoo.com', 'www.facebook.com');
%ipaddrs = ();
foreach $hostname (@hostnames) {
        map { $ipaddrs{$hostname} = inet_ntoa($_) } (gethostbyname($hostname))[4,];
}
share|improve this answer
add comment

Your Answer

 
discard

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.