Putting IP Address into bash variable. Is there a better way

前端 未结 18 1705
生来不讨喜
生来不讨喜 2020-12-07 20:09

I\'m trying to find a short and robust way to put my IP address into a bash variable and was curious if there was an easier way to do this. This is how I am currently doing

相关标签:
18条回答
  • 2020-12-07 21:09

    The following works on Mac OS (where there is no ip commnand or hostname options):

    #!/bin/bash
    
    #get interface used for defalt route (usually en0)
    IF=$(route get default |grep 'interface' |awk -F: '{print $2}');
    
    #get the IP address for inteface IF
    #does ifconfig, greps for interface plus 5 lines, greps for line with 'inet '
    IP=$(ifconfig |grep -A5 $IF | grep 'inet ' | cut -d: -f2 |awk '{print $2}');
    #get the gateway for the default route
    GW=$(route get default | awk '/gateway:/ {print $2}');
    
    0 讨论(0)
  • 2020-12-07 21:10

    In my script i did need only the network part of the IP, so I did it like that

    local=$(hostname -I | awk '{print $2}' | cut -f1,2,3 -d".")
    

    Where the cut -f1,2,3 -d"." can be read as "get first 3 parts separated by commas" To change interfaces just change $2 to your interface number, to get whole IP remove cut.

    0 讨论(0)
  • 2020-12-07 21:10

    In trying to avoid too many pipes, work on various linuxes, set an exit code, and avoiding ifconfig or other packages, I tried the whole thing in awk:

     ip addr show | awk '
         BEGIN {FS="/"}
         /^[0-9]+: eth[0-9]+.*UP*/ {ss=1}
         ss==1 && /^ +inet / {print substr($1,10); exit 0}
         END {exit 1}'
    

    and note that a particular interface can be specified after "ip addr show" if you don't want just the first eth interface. And adapting to ipv6 is a matter of looking for "inet6" instead of "inet"...

    0 讨论(0)
  • 2020-12-07 21:10

    On mac osx, you can use ipconfig getifaddr [interface] to get the local ip:

    $ ipconfig getifaddr en0
    192.168.1.30
    
    $ man ipconfig 
    
    DESCRIPTION
         ipconfig is a utility that communicates with the IPConfiguration agent to
         retrieve and set IP configuration parameters.  It should only be used in
         a test and debug context.  Using it for any other purpose is strongly
         discouraged.  Public API's in the SystemConfiguration framework are cur-
         rently the only supported way to access and control the state of IPCon-
         figuration.
    
         ...
    
         getifaddr interface-name
                     Prints to standard output the IP address for the first net-
                     work service associated with the given interface.  The output
                     will be empty if no service is currently configured or active
                     on the interface.
    
    0 讨论(0)
  • 2020-12-07 21:12
    ifconfig | grep -oP "(?<=inet addr:).*?(?=  Bcast)"
    

    When using grep to extract a portion of a line (as some other answers do), perl look-ahead and look-behind assertions are your friends.

    The quick explanation is that the first (?<=inet addr:) and last (?= Bcast) parenthesis contain patterns that must be matched, but the characters that match those patters won't be returned by grep, only the characters that are between the two patterns and match the pattern .*? that is found between the sets of parenthesis, are returned.

    Sample ifconfig output:

    eth0      Link encap:Ethernet  HWaddr d0:67:e5:3f:b7:d3  
              inet addr:10.0.0.114  Bcast:10.0.0.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1392392 errors:0 dropped:0 overruns:0 frame:0
              TX packets:1197193 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:1294730881 (1.2 GB)  TX bytes:167208753 (167.2 MB)
              Interrupt:18
    

    This will extract your IP address from the ifconfig output:

    ifconfig | grep -oP "(?<=inet addr:).*?(?=Bcast)"
    

    To assign that to a variable, use this:

    ip=$(ifconfig | grep -oP "(?<=inet addr:).*?(?=Bcast)")
    

    A slightly more in depth explanation:

    From man grep:

    -o Print only the matched (non-empty) parts of matching lines, with each such part on a separate output line.

    -P Interpret the pattern as a Perl regular expression. This is highly experimental and ‘grep -P’ may warn of unimplemented features.

    From permonks.org:

    (?<=pattern) is a positive look-behind assertion

    (?=pattern) is a positive look-ahead assertion

    -o Tells grep to only return the portion of the line that matches the pattern. The look-behinds/aheads are not considered by grep to be part of the pattern that is returned. The ? after .* is important since we want it to look for the very next look-ahead after the .* pattern is matched, and not look for the last look-ahead match. (This is not needed if we added a regex for the IP address instead of .*, but, readability).

    0 讨论(0)
  • 2020-12-07 21:14

    The ifdata command (found in the moreutils package) provides an interface to easily retrieve ifconfig data without needing to parse the output from ifconfig manually. It's achieved with a single command:

    ifdata -pa eth1
    

    Where eth1 is the name of your network interface.

    I don't know how this package behaves when ifconfig is not installed. As Syncrho stated in his answer, ifconfig has been deprecated for sometime, and is no longer found on a lot of modern distributions.

    0 讨论(0)
提交回复
热议问题