Linux/bash: How to get interface's IPv6 address?

5

4

What command can I use to get IPv6 address of an interface in a script?

Update: Output of sed from one of answers.

$ ip -6 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 fe80::224:d7ff:fed0:4f5c/64 scope link 
       valid_lft forever preferred_lft forever

The other:

$ ip addr show dev eth0 | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'
$ ip addr show dev eth0
  2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
  link/ether f0:de:f1:7b:e9:6c brd ff:ff:ff:ff:ff:ff

Ondra Žižka

Posted 2012-02-14T13:13:24.657

Reputation: 619

Which IPv6 addresses? Your interfaces' IPv6 addresses? – m0skit0 – 2012-02-14T13:27:07.680

Yes, edited, thx. – Ondra Žižka – 2012-02-21T04:33:03.697

Answers

11

You could use:

ip -6 addr

It will return all the IPv6 adresses you have configured.

Robert

Posted 2012-02-14T13:13:24.657

Reputation: 826

13

There are lots of ways you could do this.

Here is one:

ip addr show dev eth0 | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'

It is similar to Robert's answer, except strips out the address only.

Paul

Posted 2012-02-14T13:13:24.657

Reputation: 52 173

1

If you're under Linux you also can parse: /proc/net/if_inet6

First column is the full IPv6 without colons. Sixth column is the interface name.

Here a rather lengthy not optimized version (I only now the basics of awk) Maybe python/perl is a better choice.

for i in "$(grep enp0s25 /proc/net/if_inet6)"; do
    echo "$i" | awk '{
        split($1, _, "[0-9a-f]{,4}", seps)
        joined = sep = ""
        for (i=1; i in seps; i++) {
            joined = joined sep seps[i]
            sep = ":"
        }
        print joined
    }'
done

If you have GNU awk (gawk) this can be shortened to:

for i in "$(grep enp0s25 /proc/net/if_inet6)"; do
    echo "$i" | gawk '@include "join"
    {
        split($1, _, "[0-9a-f]{,4}", seps)
        print join(seps, 1, length(seps), ":")
    }'
done

You may put it in a {ba,z,}sh function to use it later.

Inrin

Posted 2012-02-14T13:13:24.657

Reputation: 11

0

The other approaches mentioned here WILL FAIL if the IF is not named eth0. And in the world of SystemD, IF names are far from predictable as IF naming conventions have changed drastically

My approach instead finds & extracts the Global Unicast Address- whatever the IF might be named. The IPv6 address could be configured for wlan0- or any other name- and my bash snippet will successfully extract and expand it as a variable in a config file requiring the listening address to be specified.

IPV6GLOBALUNICAST="$(ip -6 addr|awk '{print $2}'|grep -P '^(?!fe80)[[:alnum:]]{4}:.*/64'|cut -d '/' -f1)"

Paste below onto the CLI of a host with an IPv6 address configured to test it:

ip -6 addr|awk '{print $2}'|grep -P '^(?!fe80)[[:alnum:]]{4}:.*/64'|cut -d '/' -f1

I'm using this with great success and hasn't failed in any circumstances to date. HTH- Terrence Houlahan

F1Linux

Posted 2012-02-14T13:13:24.657

Reputation: 161