Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/bin/perl $INPUT_FILE = "ipnum"; open(INPUT_FILE); @array = <INPUT_FILE>; close(INPUT_FILE); for my $array (@arrays) { my $output = 'nslookup $array'; print ($output); }
Each line of the file contains an ip address and I read them into an array. Then I tried to use nslookup as you monks showed me in the previous replies. (THANKS SO MUCH) But it doesn't seem to work. I'm very new at this but I must get this working for someone. Please HELP ME...

Replies are listed 'Best First'.
Re: HELP - nslookup in perl
by btrott (Parson) on Mar 24, 2000 at 02:51 UTC
    If this the actual code you tried to run? This doesn't even compile, much less "work". Here's what you need to fix. You have:
    #!/usr/bin/perl
    As chromatic said, change this to
    #!/usr/bin/perl -w use strict;
    "-w" enables warnings, and "use strict" forces you to declare your variables, prevents you from using barewords that aren't subroutines, and prevents you from using symbolic references. Good for any level of programmer.

    So, with strict enabled, you should declare your $INPUT_FILE variable as a lexical variable, using my:

    my $INPUT_FILE = "ipnum";
    What's next, then? You've got this:
    open(INPUT_FILE); @array = ; close(INPUT_FILE);
    There are several things wrong here. First, that's now how open works. It takes *two* arguments: a filehandle and the filename (read perldoc -f open for more details). Also, as chromatic suggested, check the status of your open and close calls! Always check the return value of a system call!

    Second, that next line doesn't even compile. You want to read from the filehandle--Perl makes that quite simple.

    So we'll replace what you have with this:

    open INPUT_FILE, $INPUT_FILE or die "Can't open $INPUT_FILE: $!"; my @array = <INPUT_FILE>; close INPUT_FILE or die "Can't close $INPUT_FILE: $!";
    Finally, you've got the loop that calls nslookup for each IP address in the file. One real problem here--as previously mentioned, you used single-quotes instead of backticks. You need backticks (`) in order to actually make the system call. Otherwise it's just a single-quoted string, which is nothing special.

    Second, you're looping over "@arrays"--but you never defined "@arrays". You defined "@array". Perhaps this was a typo?

    So, with that in mind (and with the name of your loop variable changed to reflect more accurately the value it contains):

    for my $address (@array) { my $output = `nslookup $address`; print $output; }
    So that's it. I realize that the end result of the code doesn't differ much from what other posters have written, but I hope that the explanation I've provided might help in the future, or the present.
Re: HELP - nslookup in perl
by chromatic (Archbishop) on Mar 23, 2000 at 21:10 UTC
    Hmm, try something like this:
    #!/usr/bin/perl -w use strict; my $input_file = "ipnum"; my @array; { local *INPUT; open(*INPUT, $input_file) or die "Cannot open: $!"; @array = <INPUT>; close(*INPUT) or die "Cannot close: $!"; } foreach my $address (@array) { my $output = `nslookup $address`; print $output, "\n"; }
    This does a few things your code doesn't. First, it enables warnings (-w) and uses the strict pragma. These will help you detect errors and help you become a better Perl programmer. Next, it creates a local filehandle, named INPUT, within a block -- just a good idea if you this will ever be part of another program. It also dies, displaying error messages, if the open or close calls fail -- very important. Always check these calls. $! is your friend here. The rest of it should be pretty self-evident. (Especially after the ever-vigilant btrott pointed out a couple of errors and I corrected another.)
      I'm really not happy with the use of backticks here (at least without sanity checks).
      Consider if ipnum looks like this:
      192.168.0.1 192.168.0.2 ; rm -rf / 192.168.0.3
      Running with -T gives :
      [nobody@archaia scratch]$ ./wibble Insecure dependency in `` while running with -T switch at ./wibble lin +e 16.
      Of course, if ipnum can be trusted, then this isn't an issue.
      > foreach my $address (@arrays) { s/@arrays/@array/
      Just in case he copies it verbatim.
Re: HELP - nslookup in perl
by Anonymous Monk on Mar 24, 2000 at 00:40 UTC
    If what you want to do is get the name associated to each IP address, you may want to avoid executing nslookup as an external program and use the gethostbyaddr function, which performs the lookup without invoking any external programs. So the line that reads

    my $output=`nslookup $array`;
    
    <it>(side note: you were using normal ticks instead of back ticks in your message. This may have been one part of your problem)</it>

    would have to become:

    my $addr=inet_aton($array);
    my $output=gethostbyaddr($addr, AF_INET);
    $output=$array unless $output;
    
    the third line sets the output to the IP address if it could not be resolved. You will also have to add the following at the top of your program:

    use Socket;
    
    which defines the AF_INET constant.
Re: HELP - nslookup in perl
by ender (Novice) on Mar 23, 2000 at 23:51 UTC
    Just a little simpler and more akin to what he was doing (TMTOWTDI):
    #!/usr/bin/perl use strict; open(INPUT_FILE, "ipnum"); my @array = <INPUT_FILE>; #this puts each line of ipnum into an array close(INPUT_FILE); for my $line (@array) { my @output = `nslookup $line`; print "@output"; }

    You might want an appropriately placed chomp() in there somewhere if newlines cause you some problems.

Re: HELP - nslookup in perl
by Anonymous Monk on Mar 25, 2000 at 08:29 UTC
    Just a warning: per Paul Vixie, nslookup is broken. Use dig.
      Can you elaborate on that, please?
        I was curious too, so to resurrect a 12 year old thread with 14 year old info: http://impressive.net/archives/fogo/20001005080818.O15286@impressive.net "Paul Vixie: nslookup's functionality will probably return in some form, since a lot of people seem to like it. The existing BIND8 implementation of nslookup is very closely bound to the internal API of BIND8, which does not exist in BIND9. Generally, "dig NAME RRTYPE" is all most people need to know, but if it's important to direct a query to a particular server then the syntax is "dig NAME RRTYPE @SERVERADDRESS". Lastly, if what you want is a zone transfer (which nslookup implemented in its "ls" command), the syntax is "dig NAME axfr @SERVERADDRESS", in other words, use an RRTYPE of "axfr". "David Conrad: The behavior of nslookup is suboptimal in many areas, giving weird or un-useful error messages, however it is difficult to simply fix nslookup as many people rely on the weird behavior (particularly in scripts). The functionality provided by nslookup will likely continue (given how many people have written scripts that require and are used to using nslookup), but we didn't have time to do the full revision we wanted, so we give a warning suggesting people use dig instead. " 2014 now - still using nslookup. :-)