3

My research indicated nslookup was never really intended for scripted use: use dig instead, which with the +short option produces machine-readable output according to the query parameters.

dig +short myip.opendns.com @resolver1.opendns.com

That being said, my router does not support dig and supports nslookup. I seek to save the returned IP address a variable for a comparison with the actual IP address:

ip=$(curl --silent http://api.ipify.org/)

awk was successful on Ubuntu:

nslookup yahoo.com  | awk -F': ' 'NR==6 { print $2 } '

but returned an error on the DD-WRT router:

nslookup: can't resolve '(null)'
2001:4998:58:1836::10 media-router-fp1.prod1.media.vip.bf1.yahoo.com

END GOAL

I have CLI .sh command to update the DDNS service: I would like to execute the update command whenever the measured and stored DDNS IP address are different (CRON job to check every 5 mintues).

QUESTION

What is the simplest nslookup equivalent to said dig example above?

OBSERVATIONS, FEEDBACK & TESTING AREA

second argument added:

root@DD-WRT:/opt# nslookup mydomain.asuscomm.com  resolver1.opendns.com
Server:    208.67.222.222
Address 1: 208.67.222.222 resolver1.opendns.com

Name:      mydomain.asuscomm.com
Address 1: 7W.10X.7Y.6Z c-7W-10X-7Y-6Z.hsd1.fl.comcast.net

devnull: > /dev/null

root@DD-WRT:/opt# nslookup mydomain.asuscomm.com  > /dev/null
nslookup: can't resolve '(null)'

devnull: > /dev/null 2>&1

root@DD-WRT:/opt# nslookup mydomain.asuscomm.com  > /dev/null 2>&1
root@DD-WRT:/opt# 

type nslookup:

root@DD-WRT:~# type nslookup
nslookup is /usr/bin/nslookup

pipe to grep then to file:

root@DD-WRT:/opt# nslookup myDomain.asuscomm.com | grep Address > test.txt
nslookup: can't resolve '(null)'
root@DD-WRT:/opt# cat test.txt
Address 1: 7W.10X.7Y.6Z c-7W-10X-7Y-6Z.hsd1.fl.comcast.net

nslookup

root@DD-WRT:/opt/test# nslookup myFQDN.asuscomm.com

Name:      mydomain.asuscomm.com
Address 1: 7x.10x.7.x6x c-7x-10x-7x-6x.hsd1.fl.comcast.net

nslookup yahoo

root@DD-WRT:/opt# nslookup yahoo.com

nslookup: can't resolve '(null)'

Name:      yahoo.com
Address 1: 2001:4998:c:1023::5 media-router-fp2.prod1.media.vip.gq1.yahoo.com
Address 2: 2001:4998:58:1836::10 media-router-fp1.prod1.media.vip.bf1.yahoo.com
Address 3: 2001:4998:58:1836::11 media-router-fp2.prod1.media.vip.bf1.yahoo.com
Address 4: 2001:4998:c:1023::4 media-router-fp1.prod1.media.vip.gq1.yahoo.com
Address 5: 2001:4998:44:41d::3 media-router-fp1.prod1.media.vip.ne1.yahoo.com
Address 6: 2001:4998:44:41d::4 media-router-fp2.prod1.media.vip.ne1.yahoo.com
Address 7: 72.30.35.9 media-router-fp1.prod1.media.vip.bf1.yahoo.com
Address 8: 98.137.246.7 media-router-fp1.prod1.media.vip.gq1.yahoo.com
Address 9: 98.138.219.231 media-router-fp1.prod1.media.vip.ne1.yahoo.com
Address 10: 98.138.219.232 media-router-fp2.prod1.media.vip.ne1.yahoo.com
Address 11: 72.30.35.10 media-router-fp2.prod1.media.vip.bf1.yahoo.com
Address 12: 98.137.246.8 media-router-fp2.prod1.media.vip.gq1.yahoo.com

grep:

root@DD-WRT:/# nslookup yahoo.com | grep gq1


nslookup: can't resolve '(null)'
Address 1: 2001:4998:c:1023::4 media-router-fp1.prod1.media.vip.gq1.yahoo.com
Address 6: 2001:4998:c:1023::5 media-router-fp2.prod1.media.vip.gq1.yahoo.com
Address 7: 98.137.246.8 media-router-fp2.prod1.media.vip.gq1.yahoo.com
Address 8: 98.137.246.7 media-router-fp1.prod1.media.vip.gq1.yahoo.com

grep:

root@DD-WRT:/opt# nslookup yahoo.com | grep -o -E '([0-9][0-9]?[0-9]?\.?){4}$'

nslookup: can't resolve '(null)'

grep3:

root@DD-WRT:/opt# nslookup mydomain.asuscomm.com | grep -o -E '([0-9][^:][0-9]?[0-9]?\.?){4}' > output.txt
nslookup: can't resolve '(null)'
root@DD-WRT:/opt# cat output.txt
7W.10X.7Y.6Z
W-10X-7Y-6Z.
gatorback
  • 1,216
  • 20
  • 44
  • Can you confirm that the command you used on your router was also nslookup yahoo.com | awk -F': ' 'NR==6 { print $2 } ' – Jeff Apr 20 '19 at 12:58
  • @JeffH. Yes: the same command was copied for execution on both platforms – gatorback Apr 20 '19 at 13:00
  • What's your goal? To update your OpenDNS IP address only if it has been changed? – Kusalananda Apr 20 '19 at 13:07
  • @Kusalananda Good question. Updating DDNS through the ASUS service only if the measured (nslookup) IP address has changed. OP edited to reflect the goal. – gatorback Apr 20 '19 at 13:16
  • nslookup yahoo.com | grep -o -E '([0-9][0-9]?[0-9]?\.?){4}$' will give you just the list of IP addresses if you can then further pipe that to give you the single result you want. – Jeff Apr 20 '19 at 13:26
  • @gatorback Wouldn't updating the DDNS blindly (whether it's needed or not) be "cheaper" (as in quicker and with less network access) than doing a more complicated scripted approach? – Kusalananda Apr 20 '19 at 13:37
  • @Kusalananda It would be less work to blindly update, however, some service providers become displeased with large number of unnecessary updates, which consume their resources (abuse). By limiting the number of updates and minimize use of their resources,the probability of Asus maintaining the services is higher: abusing it will prompt them to shut it down – gatorback Apr 20 '19 at 13:51
  • @JeffH. I encourage you to post the grep solution as an answer and provide a walk through of the grep arguments (I have a beginner's understand of regular expressions). grep test results posted in OP. Should the {4} be {3} (third column)? – gatorback Apr 20 '19 at 13:59
  • @gatorback But I presume you would run this at most at reboots, right? I would doubt that updating ones DDNS once or twice, or even five times a day would be considered abuse. This is also what ASUS routers do. – Kusalananda Apr 20 '19 at 14:04
  • @Kusalananda, maybe it is overkill: the plan is to check the IP address every 5 minutes (CRON job) in a script and update only when there is a difference. I was thinking that updating every 5 minutes or even ten minutes would be abusive. Is it only necessary to run at reboot? – gatorback Apr 20 '19 at 14:09
  • @gatorback I don't think my suggestion will work for you as the behavior of nslookup on your router is not what I'm familiar with on other linux boxes. As for the {4} or {3} question, it is set at {4} because a valid IP address has four groups of digits. On my system the command I provided gives me a tidy list of just the IP addresses. Not sure why yours is throwing an error about 'null'. – Jeff Apr 20 '19 at 14:29
  • @gatorback It's definitely only necessary to update your DDNS when your public IP changes. It's unlikely to change every 5 minutes while you're actually sitting on a DHCP lease. Check the lease for how long it's valid for. It would be unnecessary to update more often than that. – Kusalananda Apr 20 '19 at 14:46
  • @gatorback: (1) You have two issues: (a) why does `nslookup` return an error, and (b) how to extract the information that you want from the non-error output of `nslookup`.  Please recognize that these are separate issues, and try not to confuse them.  (2) What do you get when you run `nslookup yourip.opendns.com`?  If you want to keep your address secret, that’s OK, but please show us what the output *looks like.*  Do you get the same `nslookup: can’t resolve '(null)'` message you get with `yahoo.com`?  Do you get an IP address?  Do you get *multiple* IP addresses  … (Cont’d) – G-Man Says 'Reinstate Monica' Apr 20 '19 at 18:55
  • (Cont’d) …  (as you do with `yahoo.com`)?  Do you get better results if you add `resolver1.opendns.com` as a second argument?  It would be especially helpful if you would run it once `> /dev/null` and once `2> /dev/null` and post both responses.  (3) Also, what do you get if you say `type nslookup`?  (4) If `nslookup` is giving you multiple IP addresses (for `yourip.opendns.com`), what do you want to get as output? … … … … … … … … Please do not respond in comments; [edit] your question to make it clearer and more complete. – G-Man Says 'Reinstate Monica' Apr 20 '19 at 18:55
  • @JeffH: Your `grep` command is failing for gatorback because your regular expression is anchored at the end (with `$`), but the question shows `nslookup` outputting IP addresses followed by a space.  Your command needs to be changed to replace the `$` with a space, or perhaps `( |$)` to match either at the end of the line *or* when followed by a space. – G-Man Says 'Reinstate Monica' Apr 20 '19 at 18:55
  • @G-Man Can I persuade you to create an 'Answer' and post suggested CLI diagnostics that I can try to copy and paste (ensures that I do not introduce any errors). – gatorback Apr 21 '19 at 01:32
  • I’m reluctant to post an Answer that isn’t an answer, and I can’t give you commands that you can use verbatim (other than `type nslookup`) because I don’t know your domain name. – G-Man Says 'Reinstate Monica' Apr 21 '19 at 02:34
  • 1
    http://jdebp.uk./FGA/nslookup-flaws.html#HiddenQueries – JdeBP Apr 21 '19 at 11:21
  • @JeffH. OP observations added to answer your questions. Please assume my domain name is mydomain.asuscomm.com in any answer you are inclined to post. Your engagement is appreciated and noted: thank you – gatorback Apr 21 '19 at 22:44
  • @gatorback Based on the output you provided from nslookup yahoo.com I've amended my suggested grep pattern to omit ipv6 results completely as it was returning portions of it. it would now be: `grep -o -E '([0-9][^:][0-9]?[0-9]?\.?){4}'` – Jeff Apr 22 '19 at 14:25
  • @JeffH. Please see grep3: So close!!! A reference for deciphering grep arguments would be appreciated. – gatorback Apr 22 '19 at 21:17
  • Can you try it against `yahoo.com` You showed a nslookup result from it with a full listing in addition to the null error and it would be good to see if it works in that context. I'm not a grep expert, but some of the basics are `[0-9]` matches any integer, `[^:]` does not match a colon (the ^ is what negates it), `?` means the preceding match could exist 0 or 1 times, the parentheses group elements of the expression together so they can be modified. In this case most of it is grouped so that I could add the `{4}` to indicate it would repeat four times. – Jeff Apr 23 '19 at 01:11

1 Answers1

1

This works:

nslookup "$D" 2>/dev/null  | grep "Address " | sed 's/.*: //g;s/ .*//g'

but note that

  • it can return more than one address so loop over them
  • grep out ipv6 if you don't want them
  • a lot of domains resolve to something different every query (like amazon randomly using cloudfront, fastly, or other ips )
user1133275
  • 5,488
  • 1
  • 19
  • 37