3

I'm trying to extract the local IP address using a cross-platform command. Until today, I was using this command:

ip route get 1 | awk '{print $NF;exit}'

But on Fedora 27 is not working because the output of ip route get 1 is:

0.0.0.1 via 192.168.1.1 dev en1  src 192.168.0.229 uid 1000
    cache

And I'm getting 1000 as the IP address. In all other systems that I have tried, the output has been always:

0.0.0.1 via 192.168.1.1 dev en1  src 192.168.0.229

I also tried using this command with same result:

ip route get 255.255.255.255 | sed -n '/src/ s/.*src //p'
3
  • NF represents the Number of fields on the line. So you are printing the last field on the line. You can print $NF-2 to get the field that is 2 from the end of the line. Jan 31, 2018 at 14:12
  • You can just use ::1. Or if you're using IPv4, 127.0.0.1. These are the loopback addresses. If on the other hand you need the address of the local network interface, bear in mind that in general there may be more than one. In many cases one can simply use 0.0.0.0 (IPv4) or ::/0 (IPv6). Jan 31, 2018 at 15:04
  • Strange.. when I do ip route get 1 on Ubuntu 20.04, I get the routing information for 1.0.0.0, not 0.0.0.1.
    – mwfearnley
    Jan 4, 2021 at 11:09

3 Answers 3

9

To print the address coming just after src (assuming all the relevant parts stay on the same line...):

ip route get 1 | sed 's/^.*src \([^ ]*\).*$/\1/;q'
2

Try this

ip route get 1 | awk '{print $7}'
2
  • In my WSL (18.04), ip route get 1 returns something like: none 1.0.0.0 via 192.168.42.1 dev eth2 proto unspec src 192.168.42.42, so the 7th field is proto there.
    – mwfearnley
    Jan 4, 2021 at 11:13
  • The answer with the sed is better. This won't work every time because sometimes it's the 6th field like in this example local 192.168.2.7 dev lo src 192.168.2.7 uid 0
    – Machta
    Feb 16, 2023 at 14:30
0

Maybe it's not what you're looking for, basically because I work with ifconfig and not with the new form of ip command to get what I want. Even so, I leave you a piece of the script that I wrote almost an year ago to obtain, among other things, the IP. Feel free to modify it as you wish. It is written in Perl and works, without any problems, in Debian 8 (Jessie).

#!/usr/bin/perl -w

use strict;                                # strict style
use warnings;                              # activate warnings
use diagnostics;                           # diagnostic failover
use 5.010;
no warnings 'experimental';

if (!@ARGV) {
    print "\nPlease enter the interface name. ie: etho, wlan0, bond0...\n\n";
    exit();

}
# This piece is for avoid misspelling or other things
if ($ARGV[0] =~ s/[\$#;@~!&*()\[\];.,:?^ `\\\/]+//g) {
    print "\nWhat are you trying?\n\n";
    exit();
}


my $sentence = "ifconfig " . $ARGV[0]; 

my @ethernet = `$sentence `; 
my $length = scalar @ethernet;

for (my $i = 0; $i < $length; $i++) {

    given ($i) {

        #MAC address
        if ($i == 0) {
            if ($ethernet[$i] =~ /([0-9A-Fa-f][0-9A-Fa-f]([:-])[0-9A-Fa-f][0-9A-Fa-f](\2[0-9A-Fa-f][0-9A-Fa-f]){4})/ ) {
                my $mac_address = $1;
                print "The MAC address of $ARGV[0] is $mac_address\n";
            } break;}

        #IP address
        if ($i == 1) {
            if($ethernet[$i] =~ /([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ ){
                my $ip_address = $1;
                print "The IP address of $ARGV[0] is $ip_address\n";
                    } break;}

        #MTU
        if ($i == 3) {
            if ($ethernet[$i] =~ /MTU:([^\sB]*)/ ) {
                my $mtu = $1;
                print "The MTU of $ARGV[0] is $mtu\n";
                }; break;}

        #Recieved package
        if ($i == 4) {
            if ($ethernet[$i] =~ /RX packets:([^\sB]*)/ ) {
                my $rx_pckg = $1;
                print "The amount of Recieved Package in $ARGV[0] is $rx_pckg\n";
                }; break;}      

        #Transmited package
        if ($i == 5) {
            if ($ethernet[$i] =~ /TX packets:([^\sB]*)/ ) {
                my $tx_pckg = $1;
                print "The amount of Transmited Package in $ARGV[0] is $tx_pckg\n";
                }; break;}      

        #Number of collisions
        if ($i == 6) {
            if ($ethernet[$i] =~ /collisions:([^\sB]*)/ ) {
                my $collisions = $1;
                print "The number of collisions in $ARGV[0] is $collisions\n";
                }; break;}

        #Total RX and TX in MB and GiB
        if ($i == 7) {
            if ($ethernet[$i] =~ /RX bytes:([^\sB]*)/ ) {
                my $rx_total_byte = $1;
                my $rx_total_mega = $rx_total_byte / 1048576;
                my $rx_total_giga = $rx_total_mega / 1024;
                print "The total amount of RecievedPackets in $ARGV[0] is $rx_total_mega Mb / $rx_total_giga GiB\n";
                }

            if ($ethernet[$i] =~ /TX bytes:([^\sB]*)/ ) {
                my $tx_total_byte = $1;
                my $tx_total_mega = $tx_total_byte / 1048576;
                my $tx_total_giga = $tx_total_mega / 1024;
                print "The total amount of RecievedPackets in $ARGV[0] is $tx_total_mega Mb / $tx_total_giga GiB\n";
                }; break;}
    }


}
1
  • 2
    A perl script using the Net::Address::IP::Local module is more easy.
    – GAD3R
    Jan 31, 2018 at 15:55

You must log in to answer this question.

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