Joe
Joe

Reputation: 371

Discovering public IP programatically in bash on Linux

I found a post that does what I need, but on Windows:

Discovering public IP programmatically

> tracert -d www.yahoo.com

`Tracing route to www-real.wa1.b.yahoo.com [69.147.76.15]
over a maximum of 30 hops:`

1    <1 ms    <1 ms    <1 ms  192.168.14.203
2     *        *        *     Request timed out.
3     8 ms     8 ms     9 ms  68.85.228.121
4     8 ms     8 ms     9 ms  68.86.165.234
5    10 ms     9 ms     9 ms  68.86.165.237
6    11 ms    10 ms    10 ms  68.86.165.242

The 68.85.228.121 is a Comcast (my provider) router. We can ping that:

ping -r 9 68.85.228.121 -n 1

Pinging 68.85.228.121 with 32 bytes of data:

Reply from 68.85.228.121: bytes=32 time=10ms TTL=253 Route: 66.176.38.51 ->

68.85.228.121 ->

68.85.228.121 ->

192.168.14.203

Voila! The 66.176.38.51 is my public IP.

This (third) answer shows a way to get my ISP's IP and then to use ping to get my IP.

It doesn't work unmodified on Linux. Traceroute works instead of tracert, but because its output is unpredictable, I'm not sure how to parse it.

I got as far as

IP="$(traceroute -d www.yahoo.com | grep ' 2 ' | sed -e 's/.*(\(.*\)).*/\1/')"

but the grep is (poorly) hard coded. I didn't see how to get ping to work as in the example.

Any input would be appreciated.

Upvotes: 0

Views: 2711

Answers (5)

n8person
n8person

Reputation: 1

IF what you want is simplicity, AND you don't mind relying on other servers (or services) try:

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

That will spit out your address only

or,

#!/bin/bash
myip="$(dig +short myip.opendns.com @resolver1.opendns.com)"
echo "myip = [${myip}]"

Upvotes: 0

Joe
Joe

Reputation: 371

I just combined what @pizza said with this answer and produced the following working script. It's not as nice as using something like traceroute, but it's a lot less complicated.

   #!/bin/bash
   content="$(wget http://checkip.dyndns.org/ -q -O -)"
   myip="$(<<< "$content" sed -e 's/.*Current IP Address: //' -e 's/<.*//')"
   echo "myip = [${myip}]"

The wget command retrieves the result of asking dyndns for my IP. Then, sed chops off everything before and after the IP address dyndns returns.

As noted elsewhere, websites such as dyndns may block such requests if they are made too frequently, but since your IP should remain constant in most situations for at least the duration of your session, if not for many days, it shouldn't be necessary to run this script very often.

Upvotes: 1

n8person
n8person

Reputation: 1

ok, i know this is an old thread, but this posting revealed some things to me, and combining it with what I've already learned, I think I've come up with a solid solution.

The grep you want is:

grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

My personal solution to find my external IP used to be:

curl icanhazip.com

Now it is:

ISP=`traceroute -M 2 -m 2 8.8.8.8 | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'` | ping -R -c 1 -t 1 -s 1 $ISP | grep RR | grep -m 1 -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > .extIP

and then

cat .extIP

Have fun!

Upvotes: 0

pizza
pizza

Reputation: 7630

This is not a reliable solution, a passive way to do this is to write a script to pull your own router's "WAN" status page. You can do that as many times as you want and nobody will complain about excessive probing.

Upvotes: 0

paulsm4
paulsm4

Reputation: 121689

Personally, I'd run this command:

wget -qO- whatismyip.org

Upvotes: 4

Related Questions