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.

I need to find my external IP address from a bash script. At the moment I use this function:

myip () { 
    lwp-request -o text checkip.dyndns.org | awk '{ print $NF }'
}

But it depends on perl-libwww, perl-html-format, perl-html-tree installed. What other ways can I get my external IP?

share|improve this question
5  
What do you mean by the external IP? The two answers so far use HTTP. The response may end up being the IP of your ISP's proxy server. (Which may be what you want.) –  billpg Oct 14 '11 at 17:21
    
@billpg: I mean the IP of the NAT router –  eugene y Oct 14 '11 at 20:09
    
Then you'll need a what-is-my-IP web service that uses HTTPS. Alas, I don't know of any. –  billpg Oct 14 '11 at 22:22
1  
@billpg ipcheckit.com –  Gilles Oct 14 '11 at 22:48

16 Answers 16

up vote 58 down vote accepted

I'd recommend getting it directly from a DNS server.

Most of the answers here all go over HTTP to a remote server. Some of them require parsing of the output, or rely on the User-Agent header to make the server respond in plain text. They also change quite frequently (go down, change their name, put up ads, might change output format etc.).

  1. The DNS response protocol is standardised (the format will stay compatible).
  2. Historically DNS services (OpenDNS, Google Public DNS, ..) tend survive much longer and are more stable, scalable and generally looked after than whatever new hip whatismyip.com HTTP service is hot today.
  3. (for those geeks that care about micro-optimisation), this method should be inherently faster (be it only by a few micro seconds).

Using dig with OpenDNS as resolver:

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

Perhaps alias it in your bashrc so it's easy to remember

alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

Responds with a plain ip address:

$ wanip
80.100.192.168
share|improve this answer
3  
you are right it's too fast.. –  Rahul Patil Jul 9 '13 at 16:24
1  
Why hasn't this been accepted? –  bitmask Apr 8 at 15:35
    
sounds like a good approach, but as of now, for my current IP in indonesia, it returns no result, whereas http based mechanisms are working. –  mc0e Oct 19 at 5:17
    
@Krinkle that's an excellent answer. Is there an equivalent for myip.opendns.com in Googles Public DNS ? –  Kannan Mohan Oct 26 at 5:11
    
Alternative is nslookup . ifcfg.me –  Eun Dec 17 at 14:03
curl -s http://whatismyip.org/

Update: whatismyip.com removed the free service to check the IP address and this no longer works.

share|improve this answer
3  
+1 I knew about whatismyip.com, but not whatismyip.org, that's awesome. –  Julian Oct 14 '11 at 15:15
    
Never knew about that one! Great site! –  IDWMaster Oct 14 '11 at 22:48
2  
@MaciekSawicki Is the -s option really necessary in this case? I tried with/without it in my fedora 15 - bash 4.2.10(1) and it worked in both ways. –  ztank1013 Oct 15 '11 at 14:05
3  
Doesn't seem to work anymore via CLI, but going to the webpage from a web browser works. I'm using openSUSE 12.1 x64. –  SaultDon Aug 16 '12 at 16:13
4  
whatismyip.com has removed the free service to check external IP. So, I'm afraid this is no longer correct. icanhazip.com still works. –  daSong Jan 17 '13 at 10:20

Since whatsmyip.org and ifconfig.me have already been mentioned:

curl -s icanhazip.com
share|improve this answer
4  
Another one: ip.appspot.com or ip.appspot.com –  Lekensteyn Nov 9 '11 at 8:31
1  
These two support IPv6. –  Josh Lee Oct 8 '12 at 17:31
    
@JoshLee, note that icanhazip also supports ipv6. Also, a note to the OP, all these curl solutions (though valid) still depend on an external library (libcurl). –  HalosGhost Jul 29 at 2:51
    
Another one: ifcfg.me –  Eun Dec 17 at 14:04
wget -O - -q http://whatismyip.org/
share|improve this answer
1  
I was not able to get my IP like this, just gives it as:<img src='ipimg.php'/> –  Yuugian Apr 4 '13 at 13:38

You can use ifconfig.me as alternative to whatismyip.org.

curl -s http://ifconfig.me

Also ifconfig.me has some additional functional. To find out what else information you can receive visit the website.

share|improve this answer

I prefer to use curlmyip.com It's as simple as:

curl curlmyip.com

It's short and simple to remember.

share|improve this answer
    
For use in bash —the intent of the OP—, you cannot do without the -s option mentioned in other answers. –  Serge Stroobandt Jul 20 at 11:53
1  
@SergeStroobandt Yes you can. All the -s switch does is run it in silent mode, ie. error messages won't be displayed. So it comes down to how he wants his script to handle errors. The command itself will return an IP address as reliably as using the -s. –  Garrett Fogerlie Jul 24 at 22:48
1  
So far, this site was the most reliable one in multiple tests. –  Amos Shapira Dec 12 at 9:05
netcat icanhazip.com 80 <<< $'GET / HTTP/1.1\nHost: icanhazip.com\n\n' | tail -n1
share|improve this answer
    
Blank output here, although the site works. Any idea why? I am behind a proxy, if that's relevant, but wget icanhazip.com works. –  l0b0 Apr 4 '13 at 11:23
    
@l0b0 Try to omit the | tail -n1 part and see what you get from the proxy –  eugene y Apr 4 '13 at 13:18
    
Nothing, just exit code 1. Ditto for netcat icanhazip.com 80. Looks like it ignores $http_proxy and friends, because specifying the proxy and port with -x just resulted in a hanging process. –  l0b0 Apr 4 '13 at 14:05
    
@l0b0: netcat proxy 3128 <<<$'GET http://icanhazip.com/ HTTP/1.0\n\n' | tail -n 1 for a basic HTTP proxy (assuming it's running on port 3128). You will obviously get the IP address of the proxy back, though. –  tripleee Jul 4 '13 at 4:07
1  
HTTP 1.0 does not have the Host: request header - name-based virtual hosting was one of the major improvements in HTTP 1.1. Either change the request to specify HTTP/1.1, or remove the Host header (I recommend the former). –  Michael Kjörling Jul 4 '13 at 7:39
curl ident.me

OR

curl ifconfig.me

OR

curl tnx.nl/ip

OR

curl ipecho.net/plain

OR

curl ip.appspot.com

OR

curl whatsmyip.akamai.com

Reference

share|improve this answer

If you want to use HTTPS to avoid some potential pitfalls:

_result=$(wget -qO- https://ipcheckit.com/)
_result="${_result##*Your IP address is<br><b>}"
printf '%s\n' "${_result%%</b></p>*}"
share|improve this answer
1  
Perhaps you could elaborate on what the potential pitfalls are that you are avoiding here? –  Caleb Oct 17 '12 at 6:27
    
The domain ipcheckit.com apparently is for sale and not hosts the IP address displaying service anymore. –  manatwork Jan 17 '13 at 11:59
    
ah, the pitfalls of writeonly scripts :) –  Ярослав Рахматуллин Jul 4 '13 at 14:07
    
@Caleb: Proxy avoidance, although apparently this doesn't work any more, so. –  Chris Down Nov 25 '13 at 19:31
    
@Chris Down the technique is still valid, you just need another SSL capable site to use it with. –  Caleb Nov 25 '13 at 21:09

Here is another alternative that depends on hosts who's business resolves around managing dynamic IP rather that "public service" sites that may go away or change format.

  1. Register your server at one of the many free dynamic dns services (e.g. no-ip.com) This will give you a DNS entry like xxx.no-ip.org.
  2. Install the service's dynamic update tool (reports IP changes to service).

To get the IP address in a script, just do:

external_ip=`dig +short xxx.no-ip.org`

Great for use in cron job to check if dynamic IP has changed and some configuration entries need to be changed.

share|improve this answer

This always works for me, I use it in my conky to get my IP address.

wget -q -O - checkip.dyndns.org | sed -e 's/[^[:digit:]\|.]//g'
share|improve this answer

Since I don't rely on the connection or on the service, I use the following code, which tries to get the IP using different services (feel free to add more):

# Get my ip address and put in a file
declare -a arr=("ipecho.net/plain" "ident.me" "tnx.nl/ip" "ip.appspot.com" "https://shtuff.it/myip/short/")
IP=$(curl -s --retry 3 --retry-delay 10 ipecho.net/plain)

while [ -z "$IP" ] # If no IP found yet, keep trying!
do
    sleep 30
    IP=$(curl -s --retry 3 --retry-delay 10 ${arr[$((  RANDOM % ${#arr[@]}  ))]})  
done

echo -n "$IP" >  /root/clientIP.txt #puts ip address in clientIP.txt
echo "Our address is $IP" 

To add more robustness (e.g. if one of the services changes their format), you could check that $IP is a valid IP using the following function:

# Verify that the parameter passed is an IP Address:
# http://zindilis.com/blog/2013/05/10/bash-check-that-string-is-ip.html
# @Author: Marios Zindilis
# @License: Creative Commons Attribution-ShareAlike 4.0 International License.
# @Date: 2013-05-10
function is_IP() {
if [ `echo $1 | grep -o '\.' | wc -l` -ne 3 ]; then
        echo "Parameter '$1' does not look like an IP Address (does not contain 3 dots).";
        exit 1;
elif [ `echo $1 | tr '.' ' ' | wc -w` -ne 4 ]; then
        echo "Parameter '$1' does not look like an IP Address (does not contain 4 octets).";
        exit 1;
else
        for OCTET in `echo $1 | tr '.' ' '`; do
                if ! [[ $OCTET =~ ^[0-9]+$ ]]; then
                        echo "Parameter '$1' does not look like in IP Address (octet '$OCTET' is not numeric).";
                        exit 1;
                elif [[ $OCTET -lt 0 || $OCTET -gt 255 ]]; then
                        echo "Parameter '$1' does not look like in IP Address (octet '$OCTET' in not in range 0-255).";
                        exit 1;
                fi
        done
fi

return 0;
}
share|improve this answer

Use curl to hit shtuff.it's ip service

curl -s http://shtuff.it/myip/short
share|improve this answer

I run a cloud service for my family and I made this quick script I run in a cron every morning at 5 because I am cheap an will not buy a static IP.

It grabs the public IP, and emails it to my users. Made it email in hyperlink format so my Mom does not have to type the ports or anything. Maybe someone else can use it to.

#!/bin/bash
ipvariable=$(wget http://ipecho.net/plain -O - -q);

echo "Today the location is http://$ipvariable:123456/foldertheyreach" | mail -s   "From your friendly cloud service provider" user1@someemail.com, user2@ect.com
share|improve this answer

ifcfg.me supports:

curl ifcfg.me
nslookup . ifcfg.me
telnet ifcfg.me
ftp ifcfg.me

IPv4 and IPv6, even more stuff with curl: ifcfg.me/?

share|improve this answer

The w3m Plaintext-Browser is great for the bash. You can use grep and tail to shorten the reply as follows:

w3m -no-cookie -dump "http://www.whatismyip.com/" | grep -A 1 -m 1 "Your IP:" | tail -n 1
share|improve this answer

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.