Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

wattengard commented May 25, 2022

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?

@RealTheSunCat
Copy link
Author

RealTheSunCat commented May 25, 2022

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?

@RealTheSunCat
Copy link
Author

RealTheSunCat commented May 26, 2022

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

@charlie39
Copy link

charlie39 commented Jun 11, 2022

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

@RealTheSunCat
Copy link
Author

RealTheSunCat commented Jun 11, 2022

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

@charlie39
Copy link

charlie39 commented Jun 11, 2022

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

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