0

I don't have much knowledge to network layer, I know the basic command to get ip address.

Have one requirement where I need to read ip address and it should work for any linux or unix system.

I am trying get the IP address of using below command.

ip route get 1.2.3.4 | grep -Po -- 'src \K\S*'.

For some system I am able to get the system IP address IPV4/IPV6.

but for some I am getting an error: RTNETLINK answers: Network is unreachable.

I tried other ip route commands but the same error.

How can I read the IP address which will work on any linux/unix system.

3
  • May I ask why you need to know that IP-address and what you want to achieve with it once you know it?
    – HBruijn
    Sep 8, 2022 at 15:38
  • @HBruijn I want to register with third party api and that need the ip address of system where my application is running. Sep 8, 2022 at 15:52
  • Then your question is an example of an XY problem , about your attempted solution rather than your actual problem. I've added my own longer answer below, because I think that a lot of the other great answers below address your attempted solution, but won't solve your real problem. - The answer by @HatLess is lacking in explanation but suggests essentially the same solution.
    – HBruijn
    Sep 9, 2022 at 9:00

6 Answers 6

3

There is no single command that works on every Linux / Unix variant.

FreeBSD-based systems for example use ifconfig.

Earlier Linux used ifconfig. ip was added later as a replacement, but one cannot trust it is available in all distributions.

First you need to more accurately define, what systems you want to support.

  • Is it only Linux-based distributions?
  • Which ones (RedHat, CentOS, Fedora, Debian or Ubuntu?)?
  • How old versions of each distribution you need to support?
  • Do you want to support other Unix variants (FreeBSD, OpenBSD, Solaris etc.)?
  • Which ones and how old?

Then you have two possibilities:

  1. Use an extra software package. It implements an abstraction where you can get the information with a uniform command. The software internally then uses OS specific methods to get the information. You need to check that the extra software package supports all of your requirements.

  2. Implement the abstraction yourself to support the required operating systems.

There is no simple answer here, and you need to do your own research to find / implement the tool to perform the task. Once you have found the tool, you can ask specific questions on using the tool here.

4
  • We are supporting linux distribution. Centos,RHEL,OEL,SUSE and UBUNTU. Sep 8, 2022 at 15:36
  • And then there can potentially also be effective IP-addresses that are often not visible to the OS or not configured there, such as the floating IP-address(es) in cloud environments.
    – HBruijn
    Sep 8, 2022 at 15:36
  • Regarding ifconfig vs iptools: I was under the impression that ifconfig was considered legacy code? Hence the transition to use iptools instead as it comes installed by default by most Linux distributions. I havent followed up on the BSD side of things though. Sep 8, 2022 at 15:39
  • ifconfig is legacy yes. However, it was not stated how old distributions need support, so ifconfig setups might need support too. At least on MacOS (FreeBSD based) still uses ifconfig Sep 8, 2022 at 17:31
2

I prefer hostname and ip on our GNU/LINUX Debian based distros

In the past i used ifconfig but now is replaced with ip and is not longer available on the most basic installations of GNU/LINUX Debian based distros and you have to install it over the net-tools

Check the manpages for hostname and ip

Like @Tero Kilkanen wrote

There is no simple answer here, and you need to do your own research to find / implement the tool to perform the task.

  1. Check the tool you need
  2. fit the commands to your need
  3. write a script that brings you to your solution

All IP

hostname -I
hostname -I | tr " " "\n"

All ipv4

hostname -I | grep -Eo '([0-9]*\.){3}[0-9]*' | tr '\n' '\n'

All ipv6

hostname -I | grep -Eo '([a-z0-9]*\:){7}[a-z0-9]*' | tr '\n' '\n'

All ip objects

ip a

All inet ip's

ip a | grep inet

All ip(lo/ipv4/ipv6) with netmask

ip a | grep inet | cut -d' ' -f6

All ip(lo/ipv4/ipv6) without netmask

ip a | grep inet | cut -d' ' -f6 | cut -d'/' -f1

If you need more informations over your network devices check this post too

0
1

Using curl, I'd use ipinfo.io

$ curl -s ipinfo.io | grep -Po 'ip[^0-9]*"\K[^"]*'
12.34.56.78

or

$ curl -s ipinfo.io | sed -En '/ip/s/[^0-9]*"([^"]*).*/\1/p'
12.34.56.78

This should work on just about every system.

2
  • these are giving different ip address than system Sep 9, 2022 at 2:15
  • Are your servers configured correctly? @RavatTailor
    – HatLess
    Sep 9, 2022 at 4:16
1

I want to register with third party API and that needs the IP address of system where my application is running.

Then asking:

I need to read the IPV4/IPV6 address and it should work for any Linux or Unix system.

is kinda the wrong thing to ask.

  • Most consumer systems and many servers as well are NOT configured with a public IPv4 address but get an IP-address from a RC 1918 private IP-address range. Their router performs NAT and the IP-address that will be used to access your API will belong to that NAT router (or the ISP) and not to the system where your application runs.
  • Many (enterprise) systems are not permitted to make a direct internet connection, but are required to use for example a HTTP Proxy to access online resources. The actual IP-address to needs to be added to the ACL will belong to the proxy and again not to the system where your application runs.
    Note: your application does support proxy settings, right?
  • Is that API actually running dual-stack and offered on both IPv4 and IPv6? Because when it is not then native IPv6 clients need to use some form of NAT64 to access the IPv4 only API and then getting the IPv6 address of system where your application runs is also not relevant...

Solution: run a second (trivial) public API yourself that returns the effective public IPv4 and/or IPv6 address that is used for internet requests. That will be the IPv4 or IPv6 address that needs to be added to the ACL.

That can be something as sophisticated your own copy of the API that powers https://ifconfig.io/ or as trivial as:

<?php
      echo $_SERVER["REMOTE_ADDR"];
?>

Or query a public API such as the one from https://ifconfig.io/ with for example curl ifconfig.io/ip.

2
  • considering the customer system where he blocked the gateway for ifconfig.io, then I will not be able to get IP Sep 9, 2022 at 10:11
  • 1
    That is why is started with : host your own public API for that. And when you can’t access that you also can’t reach your API and the whole problem becomes a moot issue right ?
    – HBruijn
    Sep 9, 2022 at 10:14
0

Simple:

ip addr will return both ipv4 and ipv6 addresses for all network interfaces.

To get ipv4 only use -4.

Like ip -4 addr.

To get ipv6 only you need to use -6.

Like: ip -6 addr.

To get the ipv4 address only for 1 interface like eth0 use the command:

ip -4 addr show dev eth0

If you want to get litterally only the ipv4 address, then you will have to use some kind of scripting for sure.

But lets say you run the ip command above. This will produce the following in my Ubuntu for WSL:

6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 172.26.105.98/20 brd 172.26.111.255 scope global eth0
       valid_lft forever preferred_lft forever

A quick and dirty way to get the ip addr only would be call the command above, store it in a variable and split text into an array whenever there is a whitespace character (space, newline, tab etc).

The text above will generate an array with 24 elements, when empty elements are removed due to multiple whitespace characters next to each other.

Printing the 15th element in the array will return 172.26.105.98/20 and if you split that element using / as a seperator will give you 172.26.105.98.

Ofc there are other ways to do it, by using perl, python or whatever you fancy this is just the dirty version.

Atm im diggin into using regular expression to grab the address from the output above.

Update 2:

Playing more with regexp where I am not particular interested in checking the ip adress is a valid ip adress, since we know it is, gives me the following command.

Using my output from above as basis for the command:

ip -4 addr show dev eth0 | egrep -o 'inet(.*)(brd|scope)' | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'

That will give the output:

172.26.105.98

A quick explanation (in case people dont read the comments).

First we pipe everything from ip addr to egrep and displaying everything between inet and brd or alternative between inet and scope.

That is what the command: egrep -o 'inet(.*)(brd|scope)' do for us.

That gives us:

inet 172.26.105.98/20 brd

on the second time through egrep we are only interested in the ip.

This is being handled by:

egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'

This leaves us with only the ipv4 address.

From here you can make a shell script that takes a random device as input and gives you the ipv4 address:

Like making a file name getip.sh with the following content:

#!/bin/bash

# Call the script with the first agument being the device
DEVICE=$1

ip -4 addr show dev $DEVICE | egrep -o 'inet(.*)(brd|scope)' | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'

You can then call the script with the command getip.sh eth0 and it will return only the ip address.

A few examples using my Ubuntu for WSL:

getip.sh lo gives 127.0.0.1

getip.sh eth0 gives 172.26.105.98

To do the same for ipv6 addresses is a bit more ... complicated as a regexp for ipv6 is longer...

Hope that answers your question?

8
  • What if multiple nic are configured? and how I can get only ip address? Can you please help me on this Sep 8, 2022 at 15:02
  • Well to begin with look at the man page for ip. Found amongst others here: linux.die.net/man/8/ip. I will update my answer with example with 1 interface. Sep 8, 2022 at 15:23
  • Thanks @Lasse, It will be really helpfull Sep 8, 2022 at 15:54
  • Tried with regexp and the closest I got so far for ipv4 addr only for eth0 interface is: ip -4 addr show dev eth0 | egrep -o 'inet(.*)brd'. It will yank out everything between inet and brd wich is the ip address in cidr form. It is a bit more tricky to get it to exclude inet and brd from the output - unless you split the text into array as suggest above. The good news is that array has only 3 elements if you split using whitespace. Sep 8, 2022 at 16:51
  • But the thing interface can be anything, So command should not be bound to particular interface Sep 8, 2022 at 17:10
0

RTNETLINK answers: Network is unreachable

ping -a 1.2.3.4

whois 1.2.3.4

And if you want to see the network path:

traceroute 1.2.3.4

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .