-1

I am trying to pipe a script to my statusbar in linux via dwm window manager and have it working fine but wanted to have a command echo "multiple" if i have more than one interface name up at the same time. This is what i have come up with so far but it doesnt want to echo "multiple" when running the script if wlan0 and usb0 are up at the same time? any help much appreciated.

#!/bin/bash

a=$(ifconfig | grep -ow "wlan0")
b="wlan0"

c=$(ifconfig | grep -ow "usb0")
d="usb0"

e=$(ifconfig | grep -ow 'usb0\|wlan0')
f="usb0\nwlan0"


if   [[ "$a" == "$b" ]] ; then
        echo -e "${b}"

elif [[ "$c" == "$d" ]] ; then
        echo -e "${d}"

elif [[ "$e" == "$f" ]] ; then
        echo "multiple"

else
        echo "not connected"
fi
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    This is _extremely_ inefficient. Consider just running `ifconfig` _once_ instead of three times. Even better, consider going straight to sysfs to get the data instead of using `ifconfig` at all. – Charles Duffy Dec 24 '20 at 02:38
  • 1
    Also, don't use `echo -e`, ever, for anything; even [the POSIX standard for `echo`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html) says to use `printf` instead when backslashes are present (which is the only case in which `-e` is meaningful, unless you're meaning the standard-compliant interpretation of the flag whereby it prints `-e` on output). For a longer explanation, see [Why is `printf` better than `echo`?](https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo) – Charles Duffy Dec 24 '20 at 02:39
  • 1
    That said, `ifconfig` shouldn't be used at all on Linux either; it hasn't been maintained by the upstream kernel team for well over a decade now, and it simply doesn't know about or understand a lot of newer features in the modern kernel's network stack. If you want a tool that does the same kind of thing ifconfig used to be used for, that's what the `iproute2` package -- the thing that provides `ip addr list`, `ip link list`, etc -- is there for. – Charles Duffy Dec 24 '20 at 02:44
  • 1
    To give you a concrete example of a kernel feature that `ifconfig` doesn't understand, try using named aliases -- ifconfig only understands numbered ones like `eth0:0` (which are the only kind that existed back when it was new), but if you create an alias named `eth0extra1`, say, `ifconfig` will just completely ignore it. – Charles Duffy Dec 24 '20 at 02:46
  • 1
    (Also, I'd strongly recommend using `=` instead of `==` in scripts -- that way you're compatible with baseline-POSIX implementations of `[`, where `=` is [the only legal string comparison operator](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html)). – Charles Duffy Dec 24 '20 at 02:47

2 Answers2

0

Put the multiple case first, and only fall through to the others if it isn't reached.

#!/usr/bin/env bash
isup() {
  [[ -e /sys/class/net/$1/carrier ]] || return 1
  [[ $(</sys/class/net/$1/carrier) = 1 ]] || return 1
  return 0
}

if isup usb0 && isup wlan0; then
  echo "multiple"
elif isup usb0; then
  echo "usb0"
elif isup wlan0; then
  echo "wlan0"
fi

This also doesn't require we have ifconfig (which isn't present in all new Linux distros -- the modern replacement is iproute2, providing the ip command), and moreover avoids running any external commands (much less running two separate external commands three times each).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Hi thanks for all your input. This script does not seem to work for me, it only outputs "multiple" when wlan0 and usb0 are connected and disconnected and when only usb0 is connected and when only wlan0 is connected. –  Dec 24 '20 at 06:02
  • I'm... not sure I understand the comment above. "only" doesn't exactly apply is it's emitting "multiple" in more circumstances than it should. Could you try to be clearer both about current and desired behavior, maybe breaking the explanation of what's wrong into more sentences? – Charles Duffy Dec 24 '20 at 13:01
  • BTW, you can test the `ifup` function on it's own. Copy and paste it into your shell, then you can do something like `if ifup usb0; then echo "usb0 is up"; else echo "usb0 is down"; fi` – Charles Duffy Dec 24 '20 at 13:03
  • Charles, on my system /sys/class/net is static not dynamic, so your script will always show multiple. –  Dec 28 '20 at 15:49
  • @dice_1, `/sys` itself is **always** dynamic. Mind, you might have the devices exist but not be active, in which case we'd need to check for a different attribute rather than just whether they exist, but they're absolutely not static on _any_ Linux system. The code above works if your hardware is hotplugged -- if `usb0` isn't physically attached to the USB bus when you don't have it active. If your real use case is different, I'd need an explanation of _how_ it's different. – Charles Duffy Dec 28 '20 at 16:00
  • @dice_1, ...the other thing is that when you run `ip addr list` (the modern equivalent to `ifconfig`), what it's doing is... reading `/sys`. So going direct to `/sys` is just going more directly to the exact same source that the data comes from regardless (though by contrast, `ifconfig` may be using an older ioctl-based interface, depending on exactly how ancient the version you're using is). – Charles Duffy Dec 28 '20 at 16:01
  • @ charles. I dont use dbus messagebus or systemd on my system so maybe that is a factor. In /sys/class/net wlan0 is always there whether up or down, it cant be disconnected from the motherboard as it is a laptop. Usb0 however can be and once it has been disconnected from the usb port it no longer shows in /sys/class/net though when it is plugged in it always shows whether it is up or down. The computer is nearly ten years old,Hope that helps –  Dec 29 '20 at 12:53
  • @dice_1, sysfs is provided by the kernel itself, not systemd/dbus/etc. However, I will need to change the code to check if wlan0 is up rather than whether it exists at all; will ping you when that's done. – Charles Duffy Dec 29 '20 at 16:24
  • @dice_1, ...done; the new version of the `ifup` function checks for whether the device reports carrier, rather than only whether the device exists. – Charles Duffy Dec 29 '20 at 17:21
  • @ charles, that version of your script works, thanks your time and patience. –  Dec 30 '20 at 12:14
  • @ charles, it just dawned on me , would ifup in your script interfere with ifupdown that i use https://packages.debian.org/buster/ifupdown –  Dec 30 '20 at 14:21
  • 1
    @dice_1, if the name is identical a function with the same name as an external command will prevent the script in which that function is defined from calling a like-named command without either fully qualifying its path or using the `command` command to tell the shell to search externally. I'd recommend renaming the function should that be a concern. – Charles Duffy Dec 30 '20 at 15:14
0

I think i may have figured this out, ifconfig is fine to use in my case. Thanks for some handy pointers Charles Duffy, what do you say of below script?

This will print on my statusbar as follows,

  1. If usb net connected = usb0
  2. If wlan0 connected = wlan0
  3. If both usb and wlan0 connected =multiple
  4. If no network = not connected
#!/usr/bin/env bash

a=$(ifconfig | grep -ow "wlan0\|usb0")
b=$'wlan0\nusb0'
c=$(printf "$b")

if      [[ "$a" = "wlan0" ]] ; then
        printf "wlan0"

elif    [[ "$a" = "usb0" ]] ; then
        printf "usb0"

elif    [[ "$a" =~ ["$c"] ]] ; then
        printf "multiple"

else
        printf "not connected"
fi