Add localhost's IP and MAC address to shell scripts
On my system, I can do:
arp | awk 'NR>1{mac[$NF]=mac[$NF]" "$3} END {for (iface in mac) print iface, mac[iface]}' | while read iface mac; do inet=$( ifconfig "$iface" | awk -v i=$iface '{for (j=1; j<NF; j++) if ($j == "inet") {print $(j+1); exit}}' ) echo $iface $inet ${mac// /,}done
The easiest way to get the MAC and IP address information for a local interface is the 'ifconfig' command, usually located at '/sbin/ifconfig'.In my case, I am using wlan0 as my primary interface:
# /sbin/ifconfig wlan0wlan0 Link encap:Ethernet HWaddr 86:75:30:9a:09:87 inet addr:10.20.30.40 Bcast:10.20.30.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1276663 errors:0 dropped:0 overruns:0 frame:0 TX packets:820927 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1233280913 (1.2 GB) TX bytes:105410513 (105.4 MB)
The simplest example to get your desired output uses a combination echo/grep/sed/awk:
echo $(/sbin/ifconfig wlan0 | \grep -oE "(HWaddr\ |inet\ addr:)[0-9a-fA-F:\.]+" | \sed 's/^\(HWaddr \|inet addr\:\)//') | \awk '{print $2"*"$1}'
Synopsis:
Using the '-o' option in grep will output only what is matched within the line, rather than the line itself.
The '-E' tells grep to expect an "extended regular expression" in the matching criteria. In this case, we are looking for entries starting with "HWaddr " or "inet addr:", followed by any combination of the characters '0-9', 'a-z', 'A-Z', ':, or '.'.
If you end the command there, you are left with two lines that look like "HWaddr 86:75:30:9a:09:87" and "inet addr:10.20.30.40".
We only want the MAC and IP addresses, so we tell sed to get rid of "HWaddr " and "inet addr:" from the beginning of the line ('^' means the beginning).
Capturing the output from this command by wrapping it in '$()' makes the two lines into one line, separated by a space. Adding this to an 'echo' command allows us to use awk to replace the space with a '*', making the final output similar to what your original 'arp | awk' command does.
What we are left with is a this:
# echo $(/sbin/ifconfig wlan0 | grep -oE "(HWaddr\ |inet\ addr:)[0-9a-fA-F:\.]+" | sed 's/^\(HWaddr \|inet addr\:\)//') | awk '{print $2"*"$1}'10.20.30.40*86:75:30:9a:09:87
You can also do it in pure Bash script, by using its embedded regular expression engine:
# IFS=$'\n' echo $(IFS=$'\n';for LINE in $(ifconfig wlan0);do if [[ "${LINE}" =~ .*(HWaddr\ |inet\ addr:)([0-9a-fA-F\:\.]+) || "${LINE}" =~ .*inet\ addr:([\d\.]+) ]];then echo ${BASH_REMATCH[2]};fi; done) | \awk '{print $2"*"$1}'172.16.17.40*a0:88:b4:78:65:04
...but it's more painful to explain :-P