The USB Equipment Commander is a lightweight daemon that is able to run commands based on the USB equipment connected to a computer. It makes it easily possible to run scripts and programs when specific USB devices are being connected or disconnected.
"Why, there's udev for that?!" you might say. Sure, but udev rules come with all sorts of limitations, making it very cumbersome to run especially Wayland-related commands. Often times, rules that trigger user-specific scripts and tools are hacky at best, given the constrains imposed by udev.
The daemon can be fully configured using a toml file.
Examples include disabling the internal keyboard when you connect an external keyboard to your laptop, triggering a script that runs a backup on an external hard drive as soon as it's being connected, opening a LUKS encrypted device when a USB stick containing a key was inserted, activate a profile-script when your network (via NetworkManager) changes, and much more.
go build .Check out the example config and create a similar config under any
of the usual configuration paths (/etc/usbec.toml,
$XDG_CONFIG_HOME/usbec.toml, ./usbec.toml).
usbecWhen usbec is started from the Sway configuration via exec it gets no signal
when Sway exits so it keeps running after you log out. Logging back in again
starts a second instance that runs every action twice. Therefore it is important
to run usbec with the --exit-with-sway flag that binds it to the Sway session:
exec usbec --exit-with-swayusbec then connects to the IPC socket in SWAYSOCK, subscribes to Sway's
shutdown event, and exits when the event arrives or the socket closes, which
also covers Sway crashing. When SWAYSOCK isn't set or the subscription fails,
usbec prints an error and exits with status 1.
In recent versions usbec can also run commands when NetworkManager's state
changes... which.. I guess.. makes it usbnetec? Anyway, each [[Networks]]
entry is a rule with a list of events, optional filters and the commands to run.
The example config contains one that shows a notification. usbec
only connects to NetworkManager when at least one rule is configured.
| Field | Meaning |
|---|---|
ID |
Required, unique among [[Networks]] entries. |
Events |
Required, at least one event from the table below. |
Types |
Optional NetworkManager connection types. |
Interfaces |
Optional interface names, such as wlan0. |
Connections |
Optional connection names or UUIDs. |
RunOnStartup |
Runs the rule once after usbec first read NetworkManager's state. Default false. |
Debounce |
Interval before the commands run. Default 0s. |
Timeout |
Limit for running all commands of the rule once. 0s or omitted means 30s. |
CancelOnChange |
Terminates running commands when a new matching event arrives. Default false. |
Run |
Required, at least one command in the format of On.Attach. |
Note: Durations are strings such as "2s" or "500ms". usbec exits with an
error at startup when a rule has an unknown key or event, a duplicate ID or no
commands.
| Event | Emitted when |
|---|---|
connection-up |
A connection is activated. |
connection-down |
An activated connection is deactivated or removed. |
default-connection-changed |
NetworkManager's primary connection changes, or another connection gets the IPv4 or IPv6 default route. |
ip-config-changed |
The IPv4 or IPv6 addresses or gateway of an activated connection change. |
connectivity-changed |
NetworkManager's connectivity state changes. |
resync |
NetworkManager was restarted and usbec read its state again. |
usbec reads NetworkManager's state after change signals and compares it with the
previous read, so events describe the difference between two reads. This, in
turn, means that e.g. connections that are already up when usbec starts don't
produce connection-up, and a rule with RunOnStartup = true runs once after
the first read instead, with the event initial-state, which can't be listed in
Events.
NetworkManager creates a new active connection for every activation, so
reconnecting to the same network produces connection-up again. A connection
counts as down as soon as it starts deactivating. Addresses are compared
together with their prefix length and the gateway to avoid DHCP renewals from
producing events.
Types, Interfaces and Connections limit a rule to certain connections. The
values within one filter are alternatives and all filters that are set have to
match the same connection. If a filter is empty it matches everything.
Types uses NetworkManager's connection types, such as 802-3-ethernet,
802-11-wireless, vpn, wireguard or bluetooth.
Connections matches the name or UUID that nmcli connection show lists.
Commands inherit usbec's environment together with the variables below.
Arguments are passed without a shell, so a command that needs a variable in an
argument has to run through sh -c, as the example config does.
| Variable | Value |
|---|---|
USBEC_NM_RULE |
Rule ID. |
USBEC_NM_EVENTS |
Event names in the batch, separated by spaces, in order of first occurrence. |
USBEC_NM_CONNECTIVITY |
unknown, none, portal, limited or full. |
USBEC_NM_CONNECTION_ID |
Connection name when all events in the batch concern the same single connection, otherwise empty. |
USBEC_NM_CONNECTION_UUID |
Its UUID, under the same condition. |
USBEC_NM_CONNECTION_TYPE |
Its type, under the same condition. |
USBEC_NM_INTERFACE |
Its interface, when it has exactly one. |
