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. ❤️

@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