4

I have to do a discover the available wifi networks by command line. I know the followed command nmcli to list the wifi:

> nmcli dev wifi list | less

which, on my Linux system, gives an output of the followed type:

*       10:7B:44:3E:F0:70  TPLINK-8853    Infra  6     130 Mbit/s  100     ****  WPA2        
        10:7B:44:3E:F0:74  TPLINK-9910    Infra  64    135 Mbit/s  99      ****  WPA2        
        88:9C:AD:2B:95:A5  GUESTS         Infra  1     260 Mbit/s  77      ***   --          
        C4:B2:39:96:AA:60  --             Infra  6     195 Mbit/s  60      ***   WPA2 802.1X
        ...

The third column of the previous list contains the SSID of the available wifi networks

The wifi "TPLINK-9910 " has a SSID with a trailing space while the wifi "TPLINK-8853" is without trailing space. I'm quite sure that starting from the output of the previous command it is not possible to get a SSID including the trailing spaces.

Are there any other options for the nmcli command that outputs the SSID of a wifi including, if present, trailing spaces?


EDIT (complete question)

I need also preserve the leading spaces in the SSID so the question to search a complete solution to my problem is:

Are there any other options for the nmcli command that outputs the SSID of a wifi including, if present, trailing spaces and leading spaces?

6
  • Tangent - is it your network? Can you rename it to make this problem go-away ? Commented Oct 8 at 18:44
  • 1
    It isn't my network. I have met this problem because for a mistake a network has a SSID with a trailing space and my scripts that used nmcli can't connect to this network. Commented Oct 8 at 20:12
  • @User051209 Does wpa_cli show the spaces? I know it escapes other unprintables, but space is technically printable: I don't expect that to matter, though, because its output is tab-separated. Try interface wlan0 (or whatever the correct name is), then scan_results. It's an interactive program, but perfectly scriptable. If this works, I'll post it as an answer. Commented Oct 8 at 21:03
  • I have to say - this choice of SSID name by whoever set it up, ranks up there with using ampersands in the user part of an email address (mum&[email protected]) or someone saying "640kB is enough..." Not the best choice. Commented Oct 9 at 0:50
  • What language are you writing your program in? Is it supposed to be connecting to any random AP it finds with the best signal, or what? Commented Oct 9 at 4:49

3 Answers 3

4

By this post I have found the option --get-value of the command nmcli. For an explanation of the option see the documentation of the command nmcli.

By this option I can specify what fields must be present in the output, and each field value is separated from the others by a colon character (':'). In this way, the command output shows the Wi-Fi network SSID complete with all leading and trailing spaces. So the command nmcli can be used as showed below:

> nmcli --get-value SSID,SECURITY dev wifi list

An example of the output of the command is the followed (there are 2 columns SSID and SECURITY seprated by : char):

TPLINK-8853:WPA2
TPLINK-9910 :WPA2
GUESTS:
:WPA2 802.1X
...

The second line of the output is TPLINK-9910 :WPA2 and it is easy to get the SSID of the Wifi because it is located between the beginning of the line and the character :.

In the output the fourth line (:WPA2 802.1X) shows an hidden wifi network (the SSID is empty).

This method solve also the problem of the leading spaces.


EDIT

As suggested by @Hans-Martin Mosner It is necessary to handle the case where the : character is contained in the SSID.
On my project the output of the nmcli command is processed by a script Python so by the split(':') method it is not difficult to get the SSID containing the character : possibly present.

Thank you to all

2
  • 1
    I later found this format, too (you can get all fields with the -t option). When formatting the output, you should handle backslash-escaped colons (I don't know which other characters might be escaped, probably a number of them). Commented Oct 9 at 13:22
  • Thanks again. I hadn't thought to the : character inside the SSID. Commented Oct 9 at 13:40
3

Have you tried the -m multiline option? It lists all fields as name and value, and I would hope that trailing blanks should be preserved. I'm not sure about leading blanks in field values, as it's not immediately obvious how the length of the field name column is determined. You may need to experiment a little.

1
  • Thank you. You are right: the problem of the trailing spaces is solved but it remains a problem with the leading spaces. I have updated my question because I need to find also SSID with leading space. Commented Oct 8 at 16:18
3

I have to manage the output of the command nmcli by a Python script.

No you don't. Python can directly access NetworkManager's API in several ways.

For example, you can call libnm through pygobject:

import gi
gi.require_version("NM", "1.0")
from gi.repository import NM

The rest is documented at: https://networkmanager.dev/docs/developers/

There's a whole example at: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/main/examples/python/gi/show-wifi-networks.py

Here's another example using raw D-Bus. While more verbose than shell scripting (maybe even more so because I used the legacy 'dbus-python' module as that's what I was already familiar with), it's still more robust than shell scripts when it comes to weird SSIDs, as they remain byte-arrays throughout the whole process:

#!/usr/bin/env python3
import dbus
import time

bus = dbus.SystemBus()

manager_obj = bus.get_object("org.freedesktop.NetworkManager",
                             "/org/freedesktop/NetworkManager")

device_paths = manager_obj.Get("org.freedesktop.NetworkManager",
                               "Devices",
                               dbus_interface="org.freedesktop.DBus.Properties")

for device_path in device_paths:
    device_obj = bus.get_object("org.freedesktop.NetworkManager", device_path)
    # device_props = device_obj.GetAll("org.freedesktop.NetworkManager.Device",
    #                                  dbus_interface="org.freedesktop.DBus.Properties")

    try:
        last_scan_ms = device_obj.Get("org.freedesktop.NetworkManager.Device.Wireless",
                                      "LastScan",
                                      dbus_interface="org.freedesktop.DBus.Properties")
    except dbus.exceptions.DBusException:
        # not a wireless interface (too lazy to check device_props["Type"])
        continue

    boottime_now = time.clock_gettime(time.CLOCK_BOOTTIME)
    #last_scan = wireless_props["LastScan"] / 1000
    last_scan = last_scan_ms / 1000
    if boottime_now - last_scan > 120:
        device_obj.RequestScan({},
                               dbus_interface="org.freedesktop.NetworkManager.Device.Wireless")
        print("Requested a fresh scan, waiting 5 seconds")
        time.sleep(5)
    else:
        print("Using recent scan results")

    ap_paths = device_obj.Get("org.freedesktop.NetworkManager.Device.Wireless",
                              "AccessPoints",
                              dbus_interface="org.freedesktop.DBus.Properties")

    for ap_path in ap_paths:
        ap_obj = bus.get_object("org.freedesktop.NetworkManager", ap_path)
        ap_props = ap_obj.GetAll("org.freedesktop.NetworkManager.AccessPoint",
                                 dbus_interface="org.freedesktop.DBus.Properties",
                                 byte_arrays=True)
        print(ap_props["HwAddress"], ap_props["Ssid"])
1
  • Thank you very much for your tip. I have to use this code on a yocto image, so I have to install some packages; for example I have tested your last example but I can't execute it on my system because I get the error No module named 'dbus'. I hope that in the near future I can install all the necessary packages and modify my code to follow your useful instructions. Thanks again. Commented Oct 10 at 12:38

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.