Shell Script Help

Greetings Linoders,

I have a file named domains_list.txt with a list of domains.

domain1.com
domain2.com
domain3.com

I need to run this command for each domain in domainslist.txt and echo it to a file named serverslist.txt.

nslookup domain1.com | grep -i "Server:" >> servers_list.txt

The output in the servers_list.txt should look something like this;

domain1.com Server:    ip address
domain2.com Server:    ip address
domain3.com Server:    ip address

I can do all these things individually, but putting them all together is proving difficult.

Maybe someone already has something like this that I can modify or someone could get me started in the direction.

Thanks much!

9 Replies

You don't mention what shell you are using, but this will work with bash (should also work with sh and probably others). Put whatever command you want to execute per-domain inside the backticks. Output on stdout, so redirect wherever you want.

cat domains_list.txt | while read domain; do echo $domain: `nslookup $domain | grep -i Server:`; done

Another option would be xargs:

cat domains_list.txt | xargs -L 1 -I DOM echo DOM `nslookup DOM | grep Server:`

I guess I tend to prefer a shell loop when the original contents are interleaved in the output (as opposed to just being an argument for the command xargs is running), but that's just personal preference.

– David

David,

Thank you for your reply. I will take a look and test this shortly. It's been one of those Mondays. :) I'll report back my results.

David,

Thanks again for the reply. Well it works to some degree. I needed to chagnged nslookup to dig. I'm not sure why I said nslookup. That should'nt change how the script works though.

If I run this from Command line;

 - dig test.com | grep ns

I get the following;

l options:  printcmd
;; Got answer:
domain.com.        60  IN  NS  ns2.dotsterhost.com.
domain.com.        60  IN  NS  ns3.dotsterhost.com.
domain.com.        60  IN  NS  ns1.dotsterhost.com.

This is good enough for me. However when I do it from command line or shell script using the command you gave me. I get the following;

Eample shell;

#!/bin/sh
 cat domains.txt | xargs -L 1 -I DOM echo DOM `dig DOM | grep ns`

Example output;

domain.com ;; global options: printcmd ;; Got answer: . 56315 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2011060601 1800 900 604800 86400

It's like the dig DOM is empty? Any ideas?

Thank you!

Not entirely sure. Something must be happening with the dig query when run beneath xargs - or somehow the string replacement is including hidden whitespace or something odd. When I try (but remove the grep part) I can see I'm getting back an NXDOMAIN error rather than a NOERROR like you do interactively, which then accounts for the difference in the output.

The shell loop works the same in either case, so I'd just use that instead. Maybe it would have been simpler not to mention the xargs case since it's not normally what I reach for in cases like this, though I did test it with nslookup and it seemed fine.

– David

David,

Sorry for the late reply, i've been super busy. I went with the first example and with minors changes got what I needed. Thanks for taking the time out to assist. It is very much appreciated.

Bill.

@shippinpie:

for i in `cat domains_list.txt`; do dig $i | grep ns >> output.txt; done


I always find it funny to see people do greps and appends inside a loop like that.

for i in `cat source_file`; do some_cmd $i; done | grep srch_string > output.txt

is so much more efficient in terms of file open/close and in terms of processes being forked. You can even reduce it one more with a while-loop

while read i; do some_cmd $i; done < source_file | grep srch_string > output.txt

Of course your original code doesn't meet the OPs requirements, but that's a different question entirely :-)

while read i
do
  dig $i ns
done < domains_list.txt | grep -w NS | grep -v '^;' > output.txt

And with some optimisation:

while read i
do
  dig $i ns
done < domains_list.txt | awk '!/^;/ && /\<ns\>/ {print $1,$5}' > output.txt</ns\>

The only difference between the 2 code variants is that I replaced the two grep's with an awk, and the awk also prints columns 1 and 5 rather than the whole line.

Thus something that looks like example.com 86400 IN NS name.server.example.com should output````
example.com name.server.example.com

I had tested it on my CentOS 5 machine and it worked fine.

Thinking about it, though, we can somplify even more; the awk part could be````
awk '$1 !~ /^;/ && $4 == "NS" { print $1,$5}'

And, of course, the dig output doesn't have $4=NS on the comment lines, so it's even simpler as````
awk '$4 == "NS" { print $1,$5}'

This makes the whole loop:````
while read i
do
  dig $i ns
done < domains_list.txt | awk '$4 == "NS" {print $1,$5}' > output.txt

Example results:````
% cat domains_list.txt
google.com
facebook.com

% while read i
do
dig $i ns
done < domains_list.txt | awk '$4 == "NS" {print $1,$5}' google.com. ns1.google.com. google.com. ns2.google.com. google.com. ns3.google.com. google.com. ns4.google.com. facebook.com. ns3.facebook.com. facebook.com. ns4.facebook.com. facebook.com. ns5.facebook.com. facebook.com. ns1.facebook.com. facebook.com. ns2.facebook.com. ````

Guys,

Thank you for the additional follow ups. I and I'm sure many others that come across this will find it very helpful!

If you have version 9 or later of dig, you can eliminate the shell loop:

$ dig -t NS -f domains_list.txt | awk '$4 == "NS" {print $1,$5}'
google.com. ns3.google.com.
google.com. ns4.google.com.
google.com. ns2.google.com.
google.com. ns1.google.com.
facebook.com. ns2.facebook.com.
facebook.com. ns3.facebook.com.
facebook.com. ns4.facebook.com.
facebook.com. ns5.facebook.com.
facebook.com. ns1.facebook.com.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct