Skip to content

Instantly share code, notes, and snippets.

@TheSunCat
Last active December 7, 2024 16:48
Show Gist options
  • Save TheSunCat/a4eda5edaba33ef622ca560988f94b08 to your computer and use it in GitHub Desktop.
Save TheSunCat/a4eda5edaba33ef622ca560988f94b08 to your computer and use it in GitHub Desktop.
USB Sounds on Linux using udev!

This is an overview of how I configured my system to play a sound when a USB device (such as a flash drive) is plugged in.

Requirements

  • Linux install with udev and systemd.
  • Root access.
  • A utility to play sounds (I used aplay).
  • Sounds to play.

Playing a sound

Using the tool aplay (found in the Arch package alsa-utils), it is easy to play an audio file: aplay insert.wav
Our goal is to run this command when a USB device is added or removed.

Systemd

One way to create triggerable events is using Systemd services. I created the following service at /etc/systemd/system/usb-insert.service:

[Unit]
Description=Play USB sound

[Service]
User=username
Type=oneshot
Environment="XDG_RUNTIME_DIR=/run/user/1000"
ExecStart=/usr/bin/aplay /etc/sounds/insert.wav
⚠️ Make sure to change the User key to your username!

The environment variable is needed for aplay to work, as systemd services don't have the same environment variables defined as your user session does.

Run sudo systemctl daemon-reload to have it register the new service.
Having placed the sound in that location, running sudo systemctl start usb-insert should now play the sound! At this point, I also created usb-remove.service that just plays a different sound.

Setting up udev

udev is a nifty tool that manages devices under /dev. It provides the ability to set up rules and run commands based on them.
You can use sudo udevadm monitor -u to see all the events that pass through it, and you should see ones marked "add" and "remove" when you add/remove devices respectively. We're going to filter them to run a command once when a USB device is added/removed.
You can then use udevadm info -a --path=/sys{/devices path from monitor} to view properties of the device. We need to filter events relating to USB devices specifically.

By editing /etc/udev/rules.d/100-usb.rules, we can add said filters. This is the configuration that worked best for me:

ACTION=="add", SUBSYSTEM=="usb", KERNEL=="*:1.0", RUN+="/bin/systemctl start usb-insert"
ACTION=="remove", SUBSYSTEM=="usb", KERNEL=="*:1.0", RUN+="/bin/systemctl start usb-remove"

If you wish to also receive notifications for SD card events, add another pair of rules for SUBSYSTEM=="block".

Make sure to apply your changes with sudo systemctl restart systemd-udevd!

We're done! 🎉

And with that, you should have working sound notifications!

If you have any suggestions to improve this, please leave them as a comment and I will incorporate them. ❤️

@wattengard
Copy link

Hmm... Could I use udev to make myself a "hardware logon token"?

  1. Take random usb thumbdrive
  2. Note down its uuid
  3. Make a usb-rule that reacts on add/remove for usb devices
  4. Make the rule filter on the thumbdrives uuid
  5. Trigger "add" to unlock the computer and "remove" to lock the computer...

Would that work?

@TheSunCat
Copy link
Author

Oh wow that's a cool idea! I don't see why it wouldn't work, though be aware the UUID is not guaranteed to be actually unique (AFAIK), since it's a randomly generated 128-bit number. Realistically, you'd be safe using it though haha.

@Archspect
Copy link

Archspect commented May 26, 2022

Spectacular work!!
Can I use different players though?

@TheSunCat
Copy link
Author

Yup! You can change the command ran by the service to do anything you want, not just aplay.

@charlie39
Copy link

so this systemd service usb-insert.service need not be enabled to work?

@TheSunCat
Copy link
Author

Nope, it's started on-demand by the udev rules.

@charlie39
Copy link

Can it be done without using a systemd service than ? like with script that udev runs directly?

@TheSunCat
Copy link
Author

Probably, though I couldn't find a way to run it as a user with the right environment directly. Given some time it's probably possible to set that up though.

@KimIV
Copy link

KimIV commented Dec 7, 2024

Благодарю! Я сделал это себе на Simply Linux. Только пошёл немного дальше и создал один сервис usb-sounds@.service, который принимает параметр и передаёт его в скрипт. А скрип уже по параметру выбирает, какой файл ему проиграть. Звуки использовал из Windows 7 "Windows Hardware Insert.wav" и "Windows Hardware Remove.wav".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment