Identify YubiKey device using dynamic device manager to send desktop notification.
Inspect device manager information
Inspect device manager events to get the YubiKey serial number.
$ udevadm monitor --property
[...] UDEV [375258.194493] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4.1 (usb) ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4.1 SUBSYSTEM=usb DEVNAME=/dev/bus/usb/002/058 DEVTYPE=usb_device PRODUCT=1050/407/543 TYPE=0/0/0 BUSNUM=002 DEVNUM=058 SEQNUM=25041 USEC_INITIALIZED=375258188457 ID_VENDOR=Yubico ID_VENDOR_ENC=Yubico ID_VENDOR_ID=1050 ID_MODEL=YubiKey_OTP+FIDO+CCID ID_MODEL_ENC=YubiKey\x20OTP+FIDO+CCID ID_MODEL_ID=0407 ID_REVISION=0543 ID_SERIAL=Yubico_YubiKey_OTP+FIDO+CCID ID_BUS=usb ID_USB_INTERFACES=:030101:030000:0b0000: ID_VENDOR_FROM_DATABASE=Yubico.com ID_MODEL_FROM_DATABASE=Yubikey 4/5 OTP+U2F+CCID ID_PATH=pci-0000:00:1d.0-usb-0:1.4.1 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_4_1 ID_SMARTCARD_READER=1 DRIVER=usb ID_SECURITY_TOKEN=1 ID_FOR_SEAT=usb-pci-0000_00_1d_0-usb-0_1_4_1 SYSTEMD_WANTS=smartcard.target SYSTEMD_USER_WANTS=smartcard.target MAJOR=189 MINOR=185 TAGS=:uaccess:security-device:systemd:seat: CURRENT_TAGS=:uaccess:security-device:systemd:seat: [...]
Serial number is not provided by default over USB descriptor.
Add Yubico PPA
Add PPA for stable Yubico software.
$ sudo add-apt-repository ppa:yubico/stable
Update package index.
$ sudo apt-get update
Use command-line utility
Install command-line personalization utility for Yubikey OTP tokens.
$ sudo apt install yubikey-personalization
Display help information.
$ ykpersonalize -h
Usage: ykpersonalize [options] -Nkey use nth key found -u update configuration without overwriting. This is only available in YubiKey 2.3 and later. EXTFLAG_ALLOW_UPDATE will be set by default -1 change the first configuration. This is the default and is normally used for true OTP generation. In this configuration, TKTFLAG_APPEND_CR is set by default. -2 change the second configuration. This is for Yubikey II only and is then normally used for static key generation. In this configuration, TKTFLAG_APPEND_CR, CFGFLAG_STATIC_TICKET, CFGFLAG_STRONG_PW1, CFGFLAG_STRONG_PW2 and CFGFLAG_MAN_UPDATE are set by default. -x swap the configuration in slot 1 and 2. This is for YubiKey 2.3 and newer only -z delete the configuration in slot 1 or 2. -sFILE save configuration to FILE instead of key. (if FILE is -, send to stdout) -iFILE read configuration from FILE. (only valid for -fycfg) (if FILE is -, read from stdin) -fformat set the data format for -s and -i valid values are ycfg or legacy. -a[XXX..] The AES secret key as a 32 (or 40 for OATH-HOTP/HMAC CHAL-RESP) char hex value (not modhex) (none to prompt for key on stdin) If -a is not used a random key will be generated. -c[XXX..] A 12 char hex value (not modhex) to use as access code for programming (this does NOT SET the access code, that's done with -oaccess=) If -c is provided without argument a code is prompted for -nXXX.. Write NDEF URI to YubiKey NEO, must be used with -1 or -2 -tXXX.. Write NDEF text to YubiKey NEO, must be used with -1 or -2 -mMODE Set the USB device configuration of the YubiKey. See the manpage for details. This is for YubiKey 3 and 4 only. -S0605.. Set the scanmap to use with the YubiKey. Must be 45 unique bytes, in hex. Use with no argument to reset to the default. This is for YubiKey 3.0 and newer only. -D0403.. Set the deviceinfo to use with this YubiKey. YubiKey 5 and newer only. -oOPTION change configuration option. Possible OPTION arguments are: fixed=xxxxxxxxxxx The public identity of key, in MODHEX. This is 0-32 characters long. uid[=xxxxxx] The uid part of the generated ticket, in HEX. MUST be 12 characters long. If argument is omitted uid is prompted for on stdin. access[=xxxxxx] New access code to set, in HEX. MUST be 12 characters long. If argument is omitted code is prompted for on stdin. oath-imf=IMF OATH Initial Moving Factor to use. oath-id[=h:OOTT...] OATH Token Identifier (none for serial-based) Ticket flags for all firmware versions: [-]tab-first set/clear TAB_FIRST [-]append-tab1 set/clear APPEND_TAB1 [-]append-tab2 set/clear APPEND_TAB2 [-]append-delay1 set/clear APPEND_DELAY1 [-]append-delay2 set/clear APPEND_DELAY2 [-]append-cr set/clear APPEND_CR Ticket flags for firmware version 2.0 and above: [-]protect-cfg2 set/clear PROTECT_CFG2 Ticket flags for firmware version 2.1 and above: [-]oath-hotp set/clear OATH_HOTP Ticket flags for firmware version 2.2 and above: [-]chal-resp set/clear CHAL_RESP Configuration flags for all firmware versions: [-]send-ref set/clear SEND_REF [-]pacing-10ms set/clear PACING_10MS [-]pacing-20ms set/clear PACING_20MS [-]static-ticket set/clear STATIC_TICKET Configuration flags for firmware version 1.x only: [-]ticket-first set/clear TICKET_FIRST [-]allow-hidtrig set/clear ALLOW_HIDTRIG Configuration flags for firmware version 2.0 and above: [-]short-ticket set/clear SHORT_TICKET [-]strong-pw1 set/clear STRONG_PW1 [-]strong-pw2 set/clear STRONG_PW2 [-]man-update set/clear MAN_UPDATE Configuration flags for firmware version 2.1 and above: [-]oath-hotp8 set/clear OATH_HOTP8 [-]oath-fixed-modhex1 set/clear OATH_FIXED_MODHEX1 [-]oath-fixed-modhex2 set/clear OATH_FIXED_MODHEX2 [-]oath-fixed-modhex set/clear OATH_MODHEX Configuration flags for firmware version 2.2 and above: [-]chal-yubico set/clear CHAL_YUBICO [-]chal-hmac set/clear CHAL_HMAC [-]hmac-lt64 set/clear HMAC_LT64 [-]chal-btn-trig set/clear CHAL_BTN_TRIG Extended flags for firmware version 2.2 and above: [-]serial-btn-visible set/clear SERIAL_BTN_VISIBLE [-]serial-usb-visible set/clear SERIAL_USB_VISIBLE [-]serial-api-visible set/clear SERIAL_API_VISIBLE Extended flags for firmware version 2.3 and above: [-]use-numeric-keypad set/clear USE_NUMERIC_KEYPAD [-]fast-trig set/clear FAST_TRIG [-]allow-update set/clear ALLOW_UPDATE [-]dormant set/clear DORMANT Extended flags for firmware version 2.4/3.1 and above: [-]led-inv set/clear LED_INV -y always commit (do not prompt) -d dry-run (don't write anything to key) -v verbose -V tool version -h help (this text)
Display utility version.
$ ykpersonalize -V
1.20.0
Dry-run operation on the first configuration slot.
$ ykpersonalize -v -d -y -u -1 -o serial-usb-visible -o serial-api-visible -o serial-btn-visible
Firmware version 5.4.3 Touch level 1285 Program sequence 1 Serial number : 18654472 Configuration data to be updated in key configuration 1: fixed: m: uid: 000000000000 key: h:00000000000000000000000000000000 acc_code: h:000000000000 ticket_flags: APPEND_CR config_flags: extended_flags: SERIAL_BTN_VISIBLE|SERIAL_USB_VISIBLE|SERIAL_API_VISIBLE|ALLOW_UPDATE Commit? (y/n) [n]: yes Attempting to write configuration to the yubikey...Not writing anything to key due to dry_run requested.
Perform operation on the first configuration slot.
$ ykpersonalize -v -y -u -1 -o serial-usb-visible -o serial-api-visible -o serial-btn-visible
Firmware version 5.4.3 Touch level 1285 Program sequence 1 Serial number : 18654472 Configuration data to be updated in key configuration 1: fixed: m: uid: 000000000000 key: h:00000000000000000000000000000000 acc_code: h:000000000000 ticket_flags: APPEND_CR config_flags: extended_flags: SERIAL_BTN_VISIBLE|SERIAL_USB_VISIBLE|SERIAL_API_VISIBLE|ALLOW_UPDATE Commit? (y/n) [n]: yes Attempting to write configuration to the yubikey... success
Use GUI utility
Install GUI personalization utility for Yubikey OTP tokens.
$ sudo apt install yubikey-personalization-gui
Execute GUI personalization utility.
$ yubikey-personalization-gui
Open settings tab and ensure that serial number visibility over USB descriptor is enabled.

Click update settings.

Ensure that configuration slot is selected and click update.
Inspect device manager information
Inspect device manager events to get the YubiKey serial number.
$ udevadm monitor --property
[...] UDEV [375336.271312] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4.1 (usb) ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4.1 SUBSYSTEM=usb DEVNAME=/dev/bus/usb/002/059 DEVTYPE=usb_device PRODUCT=1050/407/543 TYPE=0/0/0 BUSNUM=002 DEVNUM=059 SEQNUM=25091 USEC_INITIALIZED=375336265108 ID_VENDOR=Yubico ID_VENDOR_ENC=Yubico ID_VENDOR_ID=1050 ID_MODEL=YubiKey_OTP+FIDO+CCID ID_MODEL_ENC=YubiKey\x20OTP+FIDO+CCID ID_MODEL_ID=0407 ID_REVISION=0543 ID_SERIAL=Yubico_YubiKey_OTP+FIDO+CCID_0018654472 ID_SERIAL_SHORT=0018654472 ID_BUS=usb ID_USB_INTERFACES=:030101:030000:0b0000: ID_VENDOR_FROM_DATABASE=Yubico.com ID_MODEL_FROM_DATABASE=Yubikey 4/5 OTP+U2F+CCID ID_PATH=pci-0000:00:1d.0-usb-0:1.4.1 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_4_1 ID_SMARTCARD_READER=1 DRIVER=usb ID_SECURITY_TOKEN=1 ID_FOR_SEAT=usb-pci-0000_00_1d_0-usb-0_1_4_1 SYSTEMD_WANTS=smartcard.target SYSTEMD_USER_WANTS=smartcard.target MAJOR=189 MINOR=186 TAGS=:security-device:seat:systemd:uaccess: CURRENT_TAGS=:security-device:seat:systemd:uaccess: [...]
YubiKey serial number is now visible in device manager.
Create custom device manager rules
Create device manager rules to execute custom shell script.
$ cat <<EOF | sudo tee /etc/udev/rules.d/90-yubikey.rules ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1050", ATTR{idProduct}=="0407", RUN+="/usr/bin/yubikey-notify.sh" ACTION=="remove", SUBSYSTEM=="input", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0407", RUN+="/usr/bin/yubikey-notify.sh" EOF
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1050", ATTR{idProduct}=="0407", RUN+="/usr/bin/yubikey-notify.sh" ACTION=="remove", SUBSYSTEM=="input", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0407", RUN+="/usr/bin/yubikey-notify.sh"
Create custom shell script and assign names to serial numbers.
$ cat <<EOF | sudo tee /usr/bin/yubikey-notify.sh #!/bin/bash # Send notification about YubiKey device # https://sleeplessbeastie.eu/2022/01/03/how-to-identify-yubikey-using-dynamic-device-manager/ # user run directory user_run_directory="/run/user" # udev actions declare -A msg_acts=( [add]=connected [remove]=disconnected ) # YubiKey names declare -A msg_keys=( [0018654472]=Red [0018654473]=Green [0018654474]=Blue ) # set message icon export msg_icon="/usr/share/icons/hicolor/scalable/status/bluetooth-paired.svg" # set message action export msg_act="\${msg_acts[\$ACTION]:-changed}" # set message key export msg_key="\${msg_keys[\$ID_SERIAL_SHORT]:-unknown}" # send notification using dbus as each active user find \$user_run_directory -maxdepth 1 ! -path \$user_run_directory -prune -type d -exec bash -c ' for directory do uid=\$(basename \$directory) sudo -u "#\${uid}" \\ bash -c " export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/\${uid}/bus; notify-send -i \"\${msg_icon}\" \"YubiKey action!\" \"<b>\${msg_key}</b> key <b>\${msg_act}</b>\" " done' bash {} \; EOF
#!/bin/bash # Send notification about YubiKey device # https://sleeplessbeastie.eu/2022/01/03/how-to-identify-yubikey-using-dynamic-device-manager/ # user run directory user_run_directory="/run/user" # udev actions declare -A msg_acts=( [add]=connected [remove]=disconnected ) # YubiKey names declare -A msg_keys=( [0018654472]=Red [0018654473]=Green [0018654474]=Blue ) # set message icon export msg_icon="/usr/share/icons/hicolor/scalable/status/bluetooth-paired.svg" # set message action export msg_act="${msg_acts[$ACTION]:-changed}" # set message key export msg_key="${msg_keys[$ID_SERIAL_SHORT]:-unknown}" # send notification using dbus as each active user find $user_run_directory -maxdepth 1 ! -path $user_run_directory -prune -type d -exec bash -c ' for directory do uid=$(basename $directory) sudo -u "#${uid}" \ bash -c " export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${uid}/bus; notify-send -i \"${msg_icon}\" \"YubiKey action!\" \"<b>${msg_key}</b> key <b>${msg_act}</b>\" " done' bash {} \;
Ensure that executable bit is set.
$ sudo chmod +x /usr/bin/yubikey-notify.sh
Inform systemd-udevd to reload the rules.
$ sudo udevadm control --reload
Connect or disconnect YubiKey devices to see notifications.

Do you catch my drift? I love this!
Additional notes
The command-line/GUI personalization utility does not need to be installed on the operating system as it is used only to alter internal YubiKey configuration.