I want to edit the bashrc file to have a simple function called "myip" to run. As you might guess, the function myip prints only my internal IP address of my machine.
The far as I got working, this is the script:
ifconfig en1 | awk '{ print $2}' | sort
Which got my this output:
10.0.0.12
options=1<PERFORMNUD>
flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST>
fe80::daa2:5eff:fe96:ba2f%en1
d8:a2:5e:96:ba:2f
autoselect
active
I'm working on Mac OS X.
How can I get this done?
Both the following work here (CentOS 5).
ip addr show eth0 | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}'
ifconfig eth0 | awk '/inet addr/ {gsub("addr:", "", $2); print $2}'
For OS X (v10.11 (El Capitan) at least):
ifconfig en0 | awk '$1 == "inet" {print $2}'
This is the more "agnostic" way to get the IP address, regardless of you *nix system (Mac OS, Linux), interface name, and even your locale configuration:
ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d:
If you have more than one active IP, will listed each one in a separated line. If you want just the first IP, add | head -n1
to the expression:
ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" \
| grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1
And if you want the IP address of a specific interface, replace the first expression ifconfig
by ifconfig INTERFACENAME
, for example ifconfig eth0 | grep -E ...
.
These are some examples mentioned in this page that fails in some circumstances and why:
ip route ...
: theip
command isn't installed in OSX machines.hostname -I
: the-I
option is invalid in OSX.ifconfig en0 ...
: the interfaces names (eth0
,en0
) are different in Linux and OSX, and in Linux the name depends also of the interface type (ethX for ethernet connection, wlanX for wireless, etc.).python -c 'import socket; print(socket.gethostbyname(socket.gethostname()))'
: this got me127.0.1.1
(a loopback IP) in Ubuntu Linux 14.04, so doesn't work.ifconfig | grep 'inet addr:' | grep -v 127.0.0.1 | head -n1 | cut -f2 -d: | cut -f1 -d ' '
: the Geograph's post is the more close, but doesn't work in some Linux distributions withoutLANG=en
configured, because the textinet addr:
thatgrep
looks for is output with a different text in other locales, and in Mac OS that label is also different.
In case of eth0, the following works for me. Try to tweak it with the same logic.
ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'
Well, after hours of struggling I finally got it right:
ifconfig en1 | awk '{ print $2}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
That last part I had missing is just grep a pattern of IP addresses from my list.
You can use awk
to do both the selecting of the inet
line and the parsing of the IP address like so:
$ ip addr ls docker0 | awk '/inet / {print $2}' | cut -d"/" -f1
172.17.42.1
In the example above, substitute the device handle eth0
in for docker0
. Also, if you want a pure AWK implementation, you can do the "cutting" within like so:
$ ip addr ls docker0 | awk '/inet / {split($2, ary, /\//); print ary[1]}'
172.17.42.1
There is another easy way to get the IP address apart from parsing ifconfig.
hostname -I
-I, --all-ip-addresses all addresses for the host
-i, --ip-address addresses for the hostname
Ref: http://linux.die.net/man/1/hostname
Example:
[ec2-user@terraform ~]$ hostname -I
10.10.10.10
IPv4 Examples using BASH4+
Example 1, using hostname:
hostname -I|cut -d" " -f 1
Example 2, the device is known (and it never changes) :
ifconfig ens5 | grep "inet" | awk '{print $2}' | sed 's/[^0-9.]*//g'
Example 3, don't now the device (e.g. eth0, eth1, enp0s23, or wpxxx) :
ip a | awk 'BEGIN{ "hostname -I|cut -d\" \" -f 1" | getline ip} $2 ~ ip {print "Device: "$NF " IP: "$2}'
Example 4, want the network IP address:
wget -q -O /dev/stdout http://checkip.dyndns.org/ | cut -d":" -f2 | cut -d \< -f1
enjoy.
No need to do unportable ifconfig parsing in Bash. It's a trivial one-liner in Python:
python -c 'import socket; print(socket.gethostbyname(socket.gethostname()))'
You can also try this
user@linux:~$ cat script.sh
ifconfig | grep ad.*Bc | cut -d: -f2 | awk '{ print $1}'
user@linux:~$
Output
user@linux:~$ ./script.sh
192.168.1.1
10.0.1.1
user@linux:~$
Please take note that ifconfig output might be different depending on your linux version. Hence, you might want to change the script accordingly.
Btw, this is my ifconfig output
user@linux:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:10
inet addr:192.168.1.1 Bcast:192.168.56.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:112 errors:0 dropped:0 overruns:0 frame:0
TX packets:93 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:14616 (14.2 KiB) TX bytes:17776 (17.3 KiB)
eth1 Link encap:Ethernet HWaddr 00:00:00:00:00:11
inet addr:10.0.1.1 Bcast:10.0.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
user@linux:~$
If you're looking for just "inet" and not "inet6", this works for me:
/usr/bin/ifconfig eth0 | grep --word-regexp inet | awk '{print $2}'
"--word-regexp" will make grep look for the whole word "inet" and not match partials of words, i.e. "inet" won't match "inet6" - "inet" will only match lines with "inet" in them.
Similar to JSR, but with awk
and cut
in reverse order:
my_ip=$(ifconfig en1 | grep 'inet addr' | awk '{print $2}' | cut -d: -f 2)
echo ${my_ip}
This works for me:ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'
Code working on VDS/VPS too:
ifconfig | grep -A2 "venet0:0\|eth0" | grep 'inet addr:' | sed -r 's/.*inet addr:([^ ]+).*/\1/' | head -1
or
ifconfig | grep 'inet addr:' | grep -v 127.0.0.1 | head -n1 | cut -f2 -d: | cut -f1 -d ' '
Taking patch's answer, making it a bit more general,
i.e.: skipping everything till the first digit.
ifconfig eth0 | awk '/inet addr/{sub(/[^0-9]*/,""); print $1}'
Or even better:
ifconfig eth0 | awk '/inet /{sub(/[^0-9]*/,""); print $1}'
- Please note the print part at the end - changes from $2 to $1.
Using Perl Regex:
ifconfig eth0 | grep -oP '(?<= inet addr:)[^ ]+'
Explanation: grep -oP searches for an EXACT match using Perl regex.
The "tricky" part is the regex itself;
1. (?<= inet addr:)
means - that the string inet addr:
is to the LEFT of what we're looking for.
2. [^ ]+
(please notice the space after the ^ ) - it means to look for everything until the first blank - in our case it is the IP Address.
Use:
ifconfig enops3 | greb broadcast | cut -d " " -f10
Where enops3
is the interface name.
This code outputs IP addresses for all network connections (except loopback) and is portable between most OS X and Linux versions.
It's particularly useful for scripts that run on machines where:
- The active network adapter is unknown,
- notebooks that switch between Wi-Fi and Ethernet connections, and
- machines with multiple network connections.
The script is:
/sbin/ifconfig -a | awk '/(cast)/ {print $2}' | cut -d: -f2
This can be assigned to a variable in a script like this:
myip=$(/sbin/ifconfig -a | awk '/(cast)/ {print $2}' | cut -d: -f2)
Scripts can handle possible multiple addresses by using a loop to process the results, as so:
if [[ -n $myip ]]; then
count=0
for i in $myip; do
myips[count]=$i # Or process as desired
((++count))
done
numIPaddresses=$count # Optional parameter, if wanted
fi
Notes:
- It filters 'ifconfig' on "cast", as this has an added effect of filtering out loopback addresses while also working on most OS X and Linux versions.
- The final 'cut' function is necessary for proper function on Linux, but not OS X. However, it doesn't effect the OS X results - so it's left in for portability.
After trying some solutions i find this most handy, add this to your alias:
alias iconfig='ifconfig | awk '\''{if ( $1 >= "en" && $2 >= "flags" && $3 == "mtu") {print $1}; if ( $1 == "inet" || $1 == "status:"){print $0};}'\''|egrep "en|lo|inet"'
the output looks like this:
shady@Shadys-MacBook-Pro:xxxx/xxx ‹dev*›$ iconfig
lo0:
inet 127.0.0.1 netmask 0xff000000
en0:
inet 10.16.27.115 netmask 0xffffff00 broadcast 10.16.27.255
en1:
en2:
en5:
inet 192.168.2.196 netmask 0xffffff00 broadcast 192.168.2.255
ifconfig eth0 | awk '/inet addr/{sub("addr:",""); print $2}'
A simple AWK + Bash script example which may give general idea how to parse command output and mix syntaxes together.
Full code is at: https://gist.github.com/darkphase/67d7ec22d47dbebd329e
BEGIN { RS = "" ; FS = "\n" } # Change separator characters
{
while ( "'"$cmd"'" | getline ){
# print $0
if ( $1 !~ /LOOPBACK/ ){
split($1,arr," ")
print "'"$blue"'"arr[1]"'"$reset"'"
for(i = 1; i <= NF; i++) { # Loop through fields (this case lines)
split($i,arr," ")
switch ( arr[1] ) {
case "inet":
print "'"$red"'" "IPV4:" "'"$reset"'" "\n IP: " "'"$yellow"'" arr[2] "'"$reset"'" "\n NM: "arr[4]"\n BC: "arr[6]
break
case "inet6":
print "'"$red"'" "IPV6:" "'"$reset"'" "\n IP: "arr[2]"\n PL: "arr[4]
break
case "ether":
print "'"$red"'" "MAC: " "'"$reset"'" arr[2]
break
default:
}
}
print ""
}
}
}'
来源:https://stackoverflow.com/questions/23934425/parse-ifconfig-to-get-only-my-ip-address-using-bash