📅 February 4, 2024
If you use a Linux distribution, such as Ubuntu or Linux Mint, then you probably have NetworkManager installed. NetworkManager handles network connectivity, and you have probably already interacted with it via a GUI interface when setting up a network connection from the panel.
But did you know that NetworkManager can also be controlled from the command line?
nmcli is the command-line tool that allows us to perform NetworkManager functions straight from the terminal. This is good news because it means we can script NetworkManager’s behavior as boot up tasks or cron jobs. In fact, we can use nmcli to show all current network connections in a custom gnome-terminal.
Here are a few examples for nmcli.
Is nmcli Installed?
Try this in a terminal:
whereis nmcli
You should see a path like this:
nmcli: /usr/bin/nmcli /usr/share/man/man1/nmcli.1.gz
This means nmcli is present on your system. (Or you could just enter nmcli and it will show connection details.)
However, nmcli is a tool for NetworkManager, so you cannot use nmcli by itself. If NetworkManager is not present because your particular Linux distribution is implementing something else, then nmcli will not be available. Some distributions use NetworkManager while others do not. For example, Ubuntu Cinnamon uses NetworkManager, but Ubuntu Server does not, so Ubuntu Server cannot use nmcli.
systemctl status NetworkManager
A Few Examples
nmcli is a thorough utility with a long man page, so here are a few examples to show a little of what is possible.
nmcliÂ
enp0s3: connected to Wired connection 1 "Intel 82540EM" ethernet (e1000), 08:00:27:82:C0:07, hw, mtu 1500 ip4 default inet4 192.168.33.221/24 route4 192.168.33.0/24 metric 100 route4 default via 192.168.33.1 metric 100 route4 169.254.0.0/16 metric 1000 lo: unmanaged "lo" loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536 DNS configuration: servers: 192.169.213.11 domains: bubblebear.net interface: enp0s3
By itself, nmcli shows current networks connections. Shown above is a VirtualBox Xubuntu VM. This is handy for a quick glimpse on the given system.
nmcli general
nmcli monitor
Monitor connectivity in real time. As networks go up and down, they are reflected here.
nmcli connection show
nmcli connection show --active nmcli con show --active
nmcli device nmcli device status
nmcli device show enp0s3
Shows more details about a specific hardware device.
GENERAL.DEVICE: enp0s3 GENERAL.TYPE: ethernet GENERAL.HWADDR: 08:00:27:82:C0:17 GENERAL.MTU: 1500 GENERAL.STATE: 100 (connected) GENERAL.CONNECTION: Wired connection 2 GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1 WIRED-PROPERTIES.CARRIER: on IP4.ADDRESS[1]: 10.100.212.115/24 IP4.GATEWAY: 10.0.2.2 IP4.ROUTE[1]: dst = 10.100.21.0/24, nh = 0.0.0.0, mt = 100 IP4.ROUTE[2]: dst = 0.0.0.0/0, nh = 10.100.222.22, mt = 100 IP4.ROUTE[3]: dst = 169.254.0.0/16, nh = 0.0.0.0, mt = 1000 IP4.DNS[1]: 10.250.110.37 IP4.DOMAIN[1]: sunshinebear.net IP6.GATEWAY: --
If the device is not connected, you will see this instead:
GENERAL.DEVICE: enp0s9 GENERAL.TYPE: ethernet GENERAL.HWADDR: 08:00:27:12:99:DC GENERAL.MTU: 1500 GENERAL.STATE: 20 (unavailable) GENERAL.CONNECTION: -- GENERAL.CON-PATH: -- WIRED-PROPERTIES.CARRIER: off IP4.GATEWAY: -- IP6.GATEWAY: --
Custom Fields
We can choose which fields are displayed using the -f option.
nmcli -f name,device,type,state,autoconnect con show --active
This can be useful when used with the -t terse option to enable parsing where the colon is the delimiter.
nmcli -t -f name,device,type,state,autoconnect con show --active
Fields Available
You can pick and choose the fields you need from these:
- NAME
- UUID
- TYPE
- TIMESTAMP
- TIMESTAMP-REAL
- AUTOCONNECT
- AUTOCONNECT-PRIORITY
- READONLY
- DBUS-PATH
- ACTIVE
- DEVICE
- STATE
- ACTIVE-PATH
- SLAVE
- FILENAME
nmcli -p -f name,device,type,state,autoconnect con show --active
The -p (pretty print) option produces output that is easier to read in a terminal.
Scripting
Put list of network devices in a bash array
#!/bin/bash declare -a arrDevices for dev in $(nmcli -t device | grep '^[^l][^o]' | cut -f1 -d:) do arrDevices=("${arrDevices[@]}" $dev) done echo "Devices: ${arrDevices[@]}"
This grabs the device names of all network devices while excluding the loopback adapter. Names are placed in an array for future use by the script.
Get IP address with device name
“How can I list an IPv4 address with a device name?”
IP addresses are not part of the available fields, so we need to obtain the IP address separately for each specific device name that we can obtain from a field. It consists of two parts, similar to this:
Get active device (active devices have IP addresses)
dev=$(nmcli -t -f device con show --active)
Note: This bash statement will return more than one device if multiple active connections are available. This example assumes only one connection is returned for the dev variable in order to keep the example simple. A for loop (shown later) is a better approach.
Get IP address from the device
nmcli -t dev show $dev
This results in more information than we need for the device when all we need is the IP4.ADDRESS line.
GENERAL.DEVICE:enp0s3
GENERAL.TYPE:ethernet
GENERAL.HWADDR:08:00:27:82:C4:01
GENERAL.MTU:1500
GENERAL.STATE:100 (connected)
GENERAL.CONNECTION:Wired connection 2
GENERAL.CON-PATH:/org/freedesktop/NetworkManager/ActiveConnection/1
WIRED-PROPERTIES.CARRIER:on
IP4.ADDRESS[1]:100.101.23.155/24
IP4.GATEWAY:10.0.2.2
IP4.ROUTE[1]:dst = 101.101.21.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:dst = 0.0.0.0/0, nh = 10.0.2.2, mt = 100
IP4.ROUTE[3]:dst = 169.254.0.0/16, nh = 0.0.0.0, mt = 1000
IP4.DNS[1]:111.101.21.131
IP4.DOMAIN[1]:funshinebear.net
IP6.GATEWAY:
We can use grep to get just the IP4.ADDRESS line.
nmcli -t dev show $dev | grep '^IP4\.ADDRESS'
IP4.ADDRESS[1]:100.101.23.155/24
So far, so good. The -t option produces the result in a colon-delimited format, so we can use cut to extract the second field.
nmcli -t dev show enp0s3 | grep '^IP4\.ADDRESS' | cut -f2 -d:
Result
100.101.23.155/24
The output is in CIDR notation, so a further cut will remove it if desired.
nmcli -t dev show enp0s3 | grep '^IP4\.ADDRESS' | cut -f2 -d: | cut -d/ -f1
Now, we have just the IPv4 address 100.101.23.155 that can then be displayed alongside a device name.
Putting it Together
Here is a script that displays the IPv4 address with each active network device.
#!/bin/bash IFS=$'\n' # Delay to wait for network to initialize sleep 2 # Header printf "%24s %4s %15s %s\n" 'NAME' 'DEVICE' 'IPv4' 'STATE' echo '----------------------------------------------------------' for item in $(nmcli -t -f name,device,type,state con show --active): do name=$(echo $item | cut -d':' -f1) dev=$(echo $item | cut -d':' -f2) type=$(echo $item | cut -d':' -f3) state=$(echo $item | cut -d':' -f4) ipv4=$(nmcli -t dev show "$dev" | grep '^IP4\.ADDRESS' | cut -d':' -f2) printf "%24s %4s %15s %s\n" $name $dev $(echo ${ipv4} | cut -d'/' -f1) ${state} done
Why sleep?
If running this script at your own leisure after the system has booted and network connections have been made, then this is probably not necessary. However, if this is a startup script, there is the possibility that it will show unusable network information before the network device is up. If that is the case, just add a delay using sleep. Experiment with various times to find out what works best for your system.
Colorize with lolcat
./networkscript.sh | lolcat
lolcat must be installed separately.
sudo apt install lolcat
Open in a dedicated terminal window
We can open the network script in a separate gnome-terminal. This is useful for opening upon system startup.
gnome-terminal --hide-menubar --title=active-devices --geometry 80x12+100+100 -- bash -c "./networkscript.sh | lolcat && bash"
This example uses gnome-terminal (sudo apt install gnome-terminal if not present), but other terminals, such as xterm, should work. It is important to add the && bash to the end of the command to execute inside the new terminal or else the window will close too fast to see anything. bash keeps the window open until closed.
The terminal colors can be customized from the terminal preferences.
Conclusion
This article barely touches upon all that is possible using nmcli, so definitely explore its man page and experiment on your own system to truly understand its scope. Anything NetworkManager-related that you might want to control or monitor is possible with nmcli.
Have fun!