How to use pipe to parse output of a command - linux

I want to process the output of a process, say ifconfig. As you all know output of ifconfig is a list of lines containing inet addr: mask: etc. But I want to extract the ip alone[from inet addr: field] and list it. is it possible with pipe command? like
ifconfig | What should be here?
I want the output of this command as list of inet addresses (of different access points if present).

You can achieve this using awk as shown on this site. I've posted an excerpt here which produces your desired result:
ifconfig | awk '/dr:/{gsub(/.*:/,"",$2);print$2}'

You can do
ifconfig -a|grep inet| awk -F' ' '{print $2}'

Related

A confusion about the alias area of bashrc file

I want write my own alias called oepnserver. The functions of the oepnserver are:
show my ip address
use python module to start a server on current folder.
The detailed code is listed below:
alias openserver="ifconfig wlan0 |grep inet\ |awk '{print $2}' && python3 -m http.server 54188"
When I type oepnserver, my terminal only shows:
inet 172.34.162.200 netmask 255.255.224.0 broadcast 172.34.191.255
Serving HTTP on 0.0.0.0 port 54188 (http://0.0.0.0:54188/) ...
However, my expectation was
172.34.162.200
Serving HTTP on 0.0.0.0 port 54188 (http://0.0.0.0:54188/) ...
I also try to use the ifconfig wlan0 |grep inet\ |awk '{print $2}' along, and I get the correct output.
Should I use another way to combine these two commands instead of &&? Or I just made some typo?
Based on your shown code I am trying to optimize it which could be done by single awk.
ifconfig wlan0 | awk '/inet /{print $2}' && your python code
Also IMHO you should try to make this as a function rather than alias.

Get mac address for alive interface

Iam trying to get the mac_address for the interface which is up till now iam able to get this
ifconfig | grep HWaddr
eth0 Link encap:Ethernet HWaddr 98:BE:94:24:41:62
eth1 Link encap:Ethernet HWaddr 98:BE:94:24:41:63
eth2 Link encap:Ethernet HWaddr 98:BE:94:24:41:64
eth3 Link encap:Ethernet HWaddr 98:BE:94:24:41:65
usb0 Link encap:Ethernet HWaddr 9A:BE:94:24:41:61
Is there any one line command to get the mac_address for the interface link which is up ?
cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address
ip route show default | awk '/default/ {print $5}' prints your default interface name. Then you get your mac from /sys/class/net/IFACE_NAME/address
You can try these solutions:
For interfaces which are Up Use ifconfig with a Regular Expression for MAC
pattern:
ifconfig | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
Some OS like CentOS doesn't provide ifconfig, so you can use ip like this:
ip add | grep link/ether | awk '{print $2}'
For all interfaces you can just simply: cat /sys/class/net/*/address
You can try this to get the mac address of your interface. If you check the interface name and the MAC address are the first and last fields on a line with no leading whitespace.
ifconfig -a |
awk '/^[a-z]/ { iface=$1; mac=$NF; next }
/inet addr:/ { print iface, mac }'
or very simplistic, you can use this
cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address
this actually return: bc:f8:6b:bd:55:00 (sample macaddress of the eth0)

Command for printing IP address in Ubuntu not understood

It is the first time I use a Linux distribution and I find --help very difficult to use in order to unserstand the following command:
ifconfig eth0 | grep inet | awk '{ print $2 }'
Someone to explain to me please what the words of this command do? what is the name of | in english?
Thanks
The | sign called pipeline and it is an operator that sends the output of the command in it left side as the input of the command in it right side.
So basicly, you have 3 commands:
ifconfig eth0
which outputs many details on your network, then you send that output to:
grep inet
which takes only the lines that contain the word inet and send that to:
awk '{ print $2 }'
which print the just seconed word.

Get MAC address using shell script

Currently all the solution mentioned for getting the MAC address always use eth0.
But what if instead of eth0 my interfaces start with eth1. Also on OS X the interface names are different.
Also the interface eth0 may be present but is unused. i.e. not active, it doesn't have an IP.
So is there a way I could get the MAC address for the first available interface that is Active.(i.e. it has an inet address, I even don't want one having inet6).
For E.g
eth0 Link encap:Ethernet HWaddr <some addr>
inet6 addr: <some addr> Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:123
RX packets:123 errors:123 dropped:123 overruns:123 frame:123
TX packets:123 errors:123 dropped:123 overruns:123 carrier:123
collisions:123 txqueuelen:123
RX bytes:123 (123 MB) TX bytes:123 (123 KB)
Interrupt:123 Memory:00000000-00000000
eth1 Link encap:Ethernet HWaddr <some addr>
inet addr:<some addr> Bcast:<some addr> Mask:<some addr>
inet6 addr: <some addr> Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:123 Metric:123
RX packets:123 errors:123 dropped:123 overruns:123 frame:123
TX packets:123 errors:123 dropped:123 overruns:123 carrier:123
collisions:123 txqueuelen:123
RX bytes:123 (123 MB) TX bytes:123 (123 KB)
Interrupt:123 Memory:00000000-00000000
NOTE : I have changed the values of the output.
So in this case I want the HWaddr for eth1 and not eth0.
How do I find it ? Also it should work on all the Linux flavours.
You can do as follows
ifconfig <Interface ex:eth0,eth1> | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
Also you can get MAC for all interface as follows
cat /sys/class/net/*/address
For particular interface like for eth0
cat /sys/class/net/eth0/address
The best Linux-specific solution is to use sysfs:
$ IFACE=eth0
$ read MAC </sys/class/net/$IFACE/address
$ echo $IFACE $MAC
eth0 00:ab:cd:12:34:56
This method is extremely clean compared to the others and spawns no additional processes since read is a builtin command for POSIX shells, including non-BASH shells. However, if you need portability to OS X, then you'll have to use ifconfig and sed methods, since OS X does not have a virtual filesystem interface like sysfs.
$ ip route show default | awk '/default/ {print $5}'
return: eth0 (my online interface)
$ cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address
return: ec:a8:6b:bd:55:05 (macaddress of the eth0, my online interface)
Terminal image
On a modern GNU/Linux system you can see the available network interfaces listing the content of /sys/class/net/, for example:
$ ls /sys/class/net/
enp0s25 lo virbr0 virbr0-nic wlp2s0
You can check if an interface is up looking at operstate in the device directory. For example, here's how you can see if enp0s25 is up:
$ cat /sys/class/net/enp0s25/operstate
up
You can then get the MAC address of that interface with:
$ cat /sys/class/net/enp0s25/address
ff:00:ff:e9:84:a5
For example, here's a simple bash script that prints MAC addresses for active interfaces:
#!/bin/bash
# getmacifup.sh: Print active NICs MAC addresses
D='/sys/class/net'
for nic in $( ls $D )
do
echo $nic
if grep -q up $D/$nic/operstate
then
echo -n ' '
cat $D/$nic/address
fi
done
And here's its output on a system with an ethernet and a wifi interface:
$ ./getmacifup.sh
enp0s25
ff:00:ff:e9:84:a5
lo
wlp2s0
For details see the Kernel documentation
Remember also that from 2015 most GNU/Linux distributions switched to systemd, and don't use ethX interface naming scheme any more - now they use a more robust naming convention based on the hardware topology, see:
Predictable Network Interface Names
systemd/src/udev/udev-builtin-net_id.c
Observe that the interface name and the MAC address are the first and last fields on a line with no leading whitespace.
If one of the indented lines contains inet addr: the latest interface name and MAC address should be printed.
ifconfig -a |
awk '/^[a-z]/ { iface=$1; mac=$NF; next }
/inet addr:/ { print iface, mac }'
Note that multiple interfaces could meet your criteria. Then, the script will print multiple lines. (You can add ; exit just before the final closing brace if you always only want to print the first match.)
Simply run:
ifconfig | grep ether | cut -d " " -f10
OR
ip a | grep ether | cut -d " " -f6
These two example commands will grep all lines with "ether" string and cut the mac address (that we need) following the number spaces (specified in the -f option) of the grepped portion.
Tested on different Linux flavors
I know that is a little bit dated, but with basic commands, we can take the mac address of an interface:
ip link show eth0 | grep link/ether | awk '{print $2}'
Have a nice day!
oh, if you want only the mac ether mac address, you can use that:
ifconfig | grep "ether*" | tr -d ' ' | tr -d '\t' | cut -c 6-42
(work on macintosh)
ifconfig -- get all info
grep -- keep the line with address
tr -- clean all
cut -- remove the "ether" to have only the address
None of the above worked for me because my devices are in a balance-rr bond. Querying either would say the same MAC address with ip l l, ifconfig, or /sys/class/net/${device}/address, so one of them is correct, and one is unknown.
But this works if you haven't renamed the device (any tips on what I missed?):
udevadm info -q all --path "/sys/class/net/${device}"
And this works even if you rename it (eg. ip l set name x0 dev p4p1):
cat /proc/net/bonding/bond0
or my ugly script that makes it more parsable (untested driver/os/whatever compatibility):
awk -F ': ' '
$0 == "" && interface != "" {
printf "%s %s %s\n", interface, mac, status;
interface="";
mac=""
};
$1 == "Slave Interface" {
interface=$2
};
$1 == "Permanent HW addr" {
mac=$2
};
$1 == "MII Status" {
status=$2
};
END {
printf "%s %s %s\n", interface, mac, status
}' /proc/net/bonding/bond0
This was the only thing that worked for me on Armbian:
dmesg | grep -oE 'mac=.*\w+' | cut -b '5-'
I have used command hciconfig with two greps to separate the PC Mac address and I saved the MAC address to variable:
PCMAC=$( hciconfig -a | grep -E 'BD Address:' | grep -Eo '[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}' )
You can also use this command to check if MAC address is in valid format. Note, that only big chars A-F are allowed and also you need to add input for this grep command:
grep -E '[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}'
This is my solution:
ip a | grep link/ether | awk -F " " '{print $2}'
Here's an alternative answer in case the ones listed above don't work for you. You can use the following solution(s) as well, which was found here:
ip addr
OR
ip addr show
OR
ip link
All three of these will show your MAC address(es) next to link/ether. I stumbled on this because I had just done a fresh install of Debian 9.5 from a USB stick without internet access, so I could only do a very minimal install, and received
-bash: ifconfig: command not found
when I tried some of the above solutions. I figured somebody else may come across this problem as well. Hope it helps.
Get MAC adress for eth0:
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep HWADDR | cut -c 9-25
Example:
[me#machine ~]$ cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep HWADDR | cut -c 9-25
55:b5:00:10:be:10

How do I get the IP of only one Interface

When I tried ifconfig it gives me the whole all the information regarding the Network Adapter.
I tried :
system( "ifconfig -a | grep inet | "
"sed 's/\\([ ]*[^ ]*\\)\\([ ]*[^ ]*\\).*$/\\1 \\2/' "
" > address.txt" ) ;
which output two Ips :
inet addr:17.24.17.229
inet addr:127.0.0.1
But I need just the 1st one , How can I filter this out.
You might use head but...
I might be mistaking of course, but my guess is that you don't really need the first one.
You're probably looking for the one that is connected to the gateway (or the Internet).
As far as I know, the order of the IP addresses or interfaces is unspecified.
What do you want to achieve exactly ?
If you want to know what interface is "connected to the internet", a more reliable approach is to find the interface which has the default route (using route) then to use ifconfig <interface> to directly get the correct IP address.
you can reduce the use of grep and head
ifconfig -a | sed -nr -e '/inet\b/{s|^.*inet\s+addr:(.[^ \t]*).*|\1|;h}' -e '${x;p}'
I'd use iproute2's ip:
ip -o addr show dev eth0 | while read IFNUM IFNAME ADDRTYPE ADDR REST; do [ "$ADDRTYPE" == "inet" ] && echo $ADDR; done
9.87.65.43/21
(Not only because it's easier to parse, but it'll also show e.g. secondary IPs, which ifconfig can't.)
Don't look at all of the adapters, just the one you want.
system( "ifconfig -a eth0 | grep inet | "
"sed 's/\\([ ]*[^ ]*\\)\\([ ]*[^ ]*\\).*$/\\1 \\2/' "
" > address.txt" ) ;
If the output of ifconfig or ip ever changes, your program will break.
Why not not just use the SIOCGIFCONF ioctl() and get it directly from the source?
ETA: It's also unsafe to assume that any given system will have just one loopback interface and just one Ethernet with a single address.
How about 'ifconfig eth0'?
hostname -I | awk '{print $1}'

Resources