How can I display the IP address shown on eth0 using a script ?
19 Answers
For the sake of providing another option, you could use the ip addr
command this way to get the IP address:
ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1
ip addr show eth0
shows information abouteth0
grep "inet\b"
only shows the line that has the IPv4 address (if you wanted the IPv6 address, change it to"inet6\b"
)awk '{print $2}'
prints on the second field, which has the ipaddress/mask, example172.20.20.15/25
cut -d/ -f1
only takes the IP address portion.
In a script:
#!/bin/bash
theIPaddress=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
-
-
-
ip addr show eth0 | grep -P "inet6?\b" | awk '{print $2}' | cut -d/ -f1
will print both IPv4 and IPv6. Jun 4, 2020 at 8:14
Note: This answer is for older systems. If this does not work for you please consider other answers. This answer is not incorrect.
save this in a file and then run bash <filename>
#!/bin/bash
ifconfig eth0 | grep "inet addr"
being more accurate to get only number showing IP address:
#!/bin/bash
ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1
Update: If this doesn't works for you, try the other answer
Update: For Ubuntu 18+, try: (don't forget to replace eth0
with interface you need the IP for. Thanks to @ignacio )
ifconfig eth0 | grep "inet " | awk '{print $2}'
-
4of course this doesn't work in the latest ubuntu. the latest ifconfig returns "inet <ip>" instead of "inet addr <ip>"– thangNov 14, 2018 at 23:10
-
2
-
here is an updated solution for ifconfig version "net-tools 2.10-alpha" : ifconfig eth0 | grep "inet" | grep -v "inet6" | sed -e 's/^[[:space:]]*//' | cut -d ' ' -f 2 Feb 13, 2020 at 9:03
-
1
-
2quick update for
Ubuntu 18.04
:ifconfig wlan0 | grep "inet " | awk '{print $2}'
– ignacioOct 28, 2020 at 16:55
Taken from https://stackoverflow.com/a/14910952/1695680
hostname -i
However that may return a local ip address (127.0.0.1), so you may have to use, and filter:
hostname -I
From hostname's manpages:
-i, --ip-address
Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses instead.
-I, --all-ip-addresses
Display all network addresses of the host. This option enumerates all configured addresses on all network inter‐faces. The loopback interface and IPv6 link-local addresses are omitted. Contrary to option -i, this option does not depend on name resolution. Do not make any assumptions about the order of the output.
-
1for the record, I like
ip addr show label 'enp*'
better, but I is annoying parse, something likeip addr show label 'enp*' | grep -oP inet\ \\S+ | cut -d' ' -f2
can work... how pretty Nov 20, 2018 at 23:37 -
ip route | grep default | grep -oP 'dev \S+' | cut -d' ' -f 2 | xargs ip addr show dev | grep -oP 'inet6? \S+'
Apr 11, 2020 at 1:43
You should use ip
(instead of ifconfig
) as it's current, maintained, and perhaps most importantly for scripting purposes, it produces a consistent & parsable output. Following are a few similar approaches:
If you want the IPv4 address for your Ethernet interface eth0
:
$ ip -4 -o addr show eth0 | awk '{print $4}'
192.168.1.166/24
As a script:
#!/usr/bin/env bash
INTFC=eth0
MYIPV4=$(ip -4 -o addr show $INTFC | awk '{print $4}')
echo $MYIPV4
will yield: 192.168.1.166/24
as its output
The output produced above is in CIDR notation. If CIDR notation isn't wanted, it can be stripped:
$ ip -4 -o addr show eth0 | awk '{print $4}' | cut -d "/" -f 1
192.168.1.166
Another option that IMHO is "most elegant" gets the IPv4 address for whatever interface is used to connect to the specified remote host (8.8.8.8 in this case). Courtesy of @gatoatigrado in this answer:
$ ip route get 8.8.8.8 | awk '{ print $NF; exit }'
192.168.1.166
Or, as a script:
#!/usr/bin/env bash
RHOST=8.8.8.8
MYIP=$(ip route get $RHOST | awk '{ print $NF; exit }')
echo $MYIP
will yield: 192.168.1.166
as its output
This works perfectly well on a host with a single interface, but more advantageously will also work on hosts with multiple interfaces and/or route specifications.
While ip
would be my preferred approach, it's certainly not the only way to skin this cat. Here's another approach that uses hostname
if you prefer something easier/more concise:
$ hostname --all-ip-addresses | awk '{print $1}'
Or, if you want the IPv6 address:
$ hostname --all-ip-addresses | awk '{print $2}'
As a script:
#!/usr/bin/env bash
MYV4IP=$(hostname --all-ip-addresses | awk '{print $1}')
MYV6IP=$(hostname --all-ip-addresses | awk '{print $2}')
echo $MYV4IP
echo $MYV6IP
will yield: 192.168.1.166
, and 2601:7c1:103:b27:352e:e151:c7d8:3379
as its answers (assuming you have an IPv6 address assigned).
@markus-lindberg 's response is my favourite. If you add -o -4
to ip's flags then you get a much more easily parsable (and consistent) output:
ip -o -4 a | awk '$2 == "eth0" { gsub(/\/.*/, "", $4); print $4 }'
-o
stands for --oneline
, which is meant to help in exactly this kind of situations. The -4
is added to limit to the IPv4 address, which is what all the other responses imply.
-
1Love the
ip
flags. Usingcut
rather than advancedawk
wizardry:ip -o -4 addr show eth0 scope global | awk '{print $4;}' | cut -d/ -f 1
Dec 16, 2016 at 14:03 -
1@DuffJ it's probably down to a matter of personal taste. I "discovered"
cut
way after I learned aboutawk
, and I like minimising the number of commands on my pipelines. Nice suggestion in any case. Dec 17, 2016 at 6:55 -
1
-
1Very helpful. This should be the accepted answer, and this is not using the deprecated
ifconfig
which needs you to explicitly installnet-tools
in Ubuntu.– HarisJun 11, 2020 at 17:28
Here are some oneliners.....
Awk
ifconfig eth0 | awk '/inet addr/{split($2,a,":"); print a[2]}'
split function in the above awk command splits the second column based on the delimiter :
and stores the splitted value into an associative array a
. So a[2]
holds the value of the second part.
sed
ifconfig eth0 | sed -n '/inet addr/s/.*inet addr: *\([^[:space:]]\+\).*/\1/p'
In basic sed , \(...\)
called capturing group which is used to capture the characters. We could refer those captured characters through back-referencing. \([^[:space:]]\+\)
captures any character but not space one or more times.
grep
ifconfig eth0 | grep -oP 'inet addr:\K\S+'
\K
discards the previously matched characters from printing at the final and \S+
matches one or more non-space characters.
Perl
ifconfig eth0 | perl -lane 'print $1 if /inet addr:(\S+)/'
One or more non-space characters which are next to the inet addr:
string are captured and finally we print those captured characters only.
-
@edwardtorvalds added some explanation. I think this would be helpful for future readers. Feel free to ask any questions from the above commands... :) Dec 12, 2014 at 8:07
ip addr|awk '/eth0/ && /inet/ {gsub(/\/[0-9][0-9]/,""); print $2}'
This only use ip addr
which is a replacement for ifconfig
and awk
combined with substitution (gsub).
Just one more option that can be useful if you don't have awk (as it is the case in some embedded devices):
ip addr show dev eth0 scope global | grep "inet\b" | cut -d/ -f 1 | egrep -o "([[:digit:]]{1,3}[.]{1}){3}[[:digit:]]{1,3}"
Here's a good one, only uses grep as secondary command:
ip addr show eth0 | grep -oP 'inet \K\S[0-9.]+'
I don't see why you should use more commands than needed
here's for IPv4:
ip -f inet a|grep -oP "(?<=inet ).+(?=\/)"
here's for IPv4 & particular dev (eth0):
ip -f inet a show eth0|grep -oP "(?<=inet ).+(?=\/)"
for IPv6:
ip -6 -o a|grep -oP "(?<=inet6 ).+(?=\/)"
I suggest using a python library like netifaces that is specifically designed for this purpose.
sudo pip install netifaces
python -c "import netifaces; print netifaces.ifaddresses('eth0')[netifaces.AF_INET][0]['addr']"
To obtain the default network interface that is in use.
default_inf = netifaces.gateways()['default'][netifaces.AF_INET][1]
this can be used with a normal user too.
ip addr show eth0 | grep "inet " | cut -d '/' -f1 | cut -d ' ' -f6
-
he ask for eth0, this version of your script could help (also show loopback tho)
ip addr show | grep "inet " | cut -d '/' -f1 | cut -d ' ' -f6
– TiloBuntMar 25, 2017 at 17:01 -
This is pretty much the same answer as askubuntu.com/a/560466/367990, just using
cut
twice instead of a combination ofawk
andcut
to parse the output. Next time you should better check out all other answers first and ensure you don't post a duplicate solution. In this case here, I think it's arguable whether it's a duplicate or just similar, so please take it as a general hint. Thanks.– Byte Commander ♦Jul 7, 2017 at 19:49
in these days with multiples interfaces (eg if you use a docker) and naming interface by ETH is not anymore the norms
I use this command to extract the IP/Mask :
IPMASK=$(ip a s|grep -A8 -m1 MULTICAST|grep -m1 inet|cut -d' ' -f6)
So whatever how many interfaces I'll have and whatever their name, GREP will only grab the first having the MULTICAST option.
I use this command to extract only the IP without the mask :
IP=$(ip a s|grep -A8 -m1 MULTICAST|grep -m1 inet|cut -d' ' -f6|cut -d'/' -f1)
I use these command on different BDS & NIX it never fail ;)
Yet another way (assuming you don't want a CIDR
address and want IPv4
):
$ ip -br -4 addr show dev eth0 | awk '{split($3,a,"/"); print a[1]}'
- Uses the
ip
command which is notdeprecated
- Uses only one command for filtering
This is the shortest way I could find:
ip -f inet addr show $1 | grep -Po 'inet \K[\d.]+'
Replace $1
with your network interface.
ip -f inet
tells ip to only return values for the inet (ipv4) family.
grep -Po
tells grep to interperate the next value as a perl-regex, and only print the matching values.
The regex \K[\d.]+
says "throw away everything up to this point (\K), and match as many numeric values followed by a dot in a row as possible". This will therefore only match the IP address and ignore everything after it, including the shortform \XX subnet mask.
In my script I'm using something like that:
re="inet[[:space:]]+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)"
if [[ $(ip addr show eth0) =~ $re ]]; then
echo ${BASH_REMATCH[1]}
else
echo "Cannot determin IP" 1>&2
fi
It doesn't spawn any process.
If eth0 has multiple IPs and you are looking for a public one here is an example of ignoring the 2 most common internal IP address ranges.
ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep --invert-match -P '^(10\.|192\.168\.)'
This ignores 10.0.0.0/8 and 192.168.0.0/16 IPs.
Yes, you can do it like the other entries suggest, but you can also do it like a bauss:
#!/bin/bash
#
# IPs Table
type column &>/dev/null || apt-get install -yq bsdextrautils
links() { ip link | awk '/^[0-9]+:/ { sub(":", "", $2); sub("@.*", "", $2 ); print $2; }'; }
ipof() { ip addr show ${1:-enp6s0} | awk ' /link.ether/ { print "mac", $2 }
/inet6*/ { print $1, $2 }'; }
( echo dev inet inet6 mac
for i in `links`; do
unset ips a b c d
ips=$(ipof $i)
if [[ -z $ips ]]; then
mac=.
inet=.
inet6=.
else
read -s -r -d ';' _ mac _ inet _ inet6 <<< "$ips;"
if [[ -z $inet6 ]] && [[ $inet =~ :: ]]; then
inet6=$inet
inet=
fi
fi
echo $i ${inet:--} ${inet6:--} ${mac:--}
done; ) | column -t
The script is from my collection
Sample output A:
dev inet inet6 mac
lo 127.0.0.1/8 ::1/128 00:00:00:00:00:00
enp6s0 192.168.0.4/24 fe80::aaa1:59ff:fe50:85ea/64 a8:a1:59:50:85:ea
enp4s0d1 - - 24:8a:07:6b:5d:52
ibp4s0 - - 80:00:02:20:fe:80:00:00:00:00:00:00:24:8a:07:03:00:6b:5d:51
virbr0 192.168.122.1/24 - 52:54:00:f3:77:52
virbr1 192.168.39.1/24 - 52:54:00:cf:77:c6
vboxnet0 - - 0a:00:27:00:00:00
vboxnet1 - - 0a:00:27:00:00:01
vboxnet2 - - 0a:00:27:00:00:02
vboxnet3 - - 0a:00:27:00:00:03
vboxnet4 - - 0a:00:27:00:00:04
Sample output B:
dev inet inet6 mac
lo 127.0.0.1/8 ::1/128 00:00:00:00:00:00
ens3 10.40.237.34/18 fe80::8de:f6ff:fe19:f315/64 0a:de:f6:19:f3:15
lxcbr0 172.16.0.1/16 fe80::216:3eff:fe00:0/64 00:16:3e:00:00:00
vaf.sta.RsuBSCQ - fe80::fc91:4fff:fed1:6adc/64 fe:91:4f:d1:6a:dc
vaf.cra.G4EHHKb - fe80::fc47:69ff:fe86:abc6/64 fe:47:69:86:ab:c6
vaf.com.t2VC1vD - fe80::fc25:cff:fec5:515b/64 fe:25:0c:c5:51:5b
vaf.lor.cXYkGKF - fe80::fce8:6dff:fed1:8d08/64 fe:e8:6d:d1:8d:08
vaf.iff.2I4P4ay - fe80::fca0:6dff:fe33:e198/64 fe:a0:6d:33:e1:98
vaf.bag.etDqGZ3 - fe80::fca6:c9ff:fe17:8e4f/64 fe:a6:c9:17:8e:4f
vaf.bor.L9tqMch - fe80::fc90:92ff:fe48:bf48/64 fe:90:92:48:bf:48
vaf.dan.GhojJo8 - fe80::fc0c:71ff:feaa:8b81/64 fe:0c:71:aa:8b:81
vaf.tru.ZuH5xfb - fe80::fc2e:21ff:fe91:2ce5/64 fe:2e:21:91:2c:e5
vaf.huo.6ii1Tyy - fe80::fcbe:fbff:fe59:44f5/64 fe:be:fb:59:44:f5
vaf.nwt.CFoTS9J - fe80::fc5d:3fff:feac:917f/64 fe:5d:3f:ac:91:7f
vethe8qi4n - fe80::fca2:10ff:feec:5e2b/64 fe:a2:10:ec:5e:2b
vaf.cra.6gHyk8E - fe80::fc23:4bff:fe2c:e9b/64 fe:23:4b:2c:0e:9b