Mastering udev Rules: Fix Shifting USB Names and Automate Linux Hardware

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

The Frustration of Shifting Device Names

I once nearly wiped a production database because a backup script I wrote targeted /dev/sdb1. It worked for weeks until I plugged in a spare thumb drive and rebooted. Suddenly, my backup drive was /dev/sdc1, and my script was blindly trying to dump data into a random 16GB installer stick. That was my wake-up call to start using udev.

On Linux, udev is the device manager living in the /dev directory. It watches the kernel, catches the moment hardware is plugged in, and applies specific rules to determine the device name and access permissions. Whether you want an Arduino to always mount at /dev/arduino or need a script to fire the second a camera connects, udev is your tool.

Quick start: A 5-minute udev rule

Let’s skip the theory and jump straight into a solution. Say you have an external SSD that needs universal read/write permissions (0666) and a name that never changes, regardless of which port you use.

1. Identify your hardware

Plug in the device and grab its IDs with lsusb:

lsusb
# Output example:
# Bus 002 Device 003: ID 0bc2:ab44 Seagate RSS LLC Expansion Portable

In this case, 0bc2 is your idVendor and ab44 is the idProduct.

2. Create the rule file

Linux processes udev rules in /etc/udev/rules.d/ alphabetically. To ensure yours takes priority, start the filename with a high number like 99.

sudo nano /etc/udev/rules.d/99-external-ssd.rules

3. Write the logic

Drop this line into the file, swapping in your specific IDs:

SUBSYSTEM=="usb", ATTRS{idVendor}=="0bc2", ATTRS{idProduct}=="ab44", MODE="0666", SYMLINK+="backup_disk"

4. Reload the system

Force udev to recognize the new instructions:

sudo udevadm control --reload-rules
sudo udevadm trigger

Now, every time you plug in that drive, a symlink appears at /dev/backup_disk. No more guessing names.

Deep dive: How udev rules actually work

Think of a udev rule as a simple logic gate: If [Match Keys], then [Assignment Keys].

Match Keys (The ‘If’ statement)

These verify if a device matches your criteria using the == operator.

  • KERNEL: Filters by the kernel’s default name (like sd* or ttyUSB*).
  • SUBSYSTEM: Targets the device category (e.g., block for disks, net for cards).
  • ATTRS{attribute}: Checks hardware-level details like serial numbers or manufacturer strings.

Assignment Keys (The ‘Then’ statement)

When udev finds a match, it executes these actions using = or +=.

  • SYMLINK: Creates a friendly alias in /dev. Use this instead of NAME.
  • OWNER, GROUP, MODE: Dictates who can actually use the device.
  • RUN: Triggers an external script.

The Power of udevadm info

Standard lsusb output is often too thin for complex rules. To see every attribute udev can track, use the info command to walk the device tree:

udevadm info -a -p $(udevadm info -q path -n /dev/sdb)

This command spits out a list of every parent device and its attributes. One crucial rule: You can pull attributes from different parents, but you cannot mix attributes from two different parent devices in a single rule line.

Advanced usage: Automation and Persistence

Once you’ve mastered symlinks, you can start automating your entire workflow.

Locking Down Network Interface Names

Tired of eth0 becoming eth1 after a kernel update? Match your NIC by its MAC address to lock it down:

SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:e0:4c:53:44:58", NAME="wan_internal"

Auto-triggering Photo Syncs

This is where things get interesting. You can trigger a script to run automatically when a specific SD card is inserted:

SUBSYSTEM=="block", ACTION=="add", ATTRS{serial}=="5744-2D58", RUN+="/usr/local/bin/backup_photos.sh"

Heads up: udev will hang if your script takes too long. If your task lasts more than 5 seconds, use systemd-run or background the process to keep the system responsive.

Practical tips from the field

I’ve managed over 15 Linux servers for 4 years, and these three rules have saved me countless hours of troubleshooting.

1. Test before you break things

Never assume a rule works just because it looks right. Use udevadm test to simulate a device event. It tells you exactly which rules will trigger without you having to touch a single cable.

# Simulate an event for /dev/sdb
udevadm test $(udevadm info -q path -n /dev/sdb)

2. Watch the live stream

If a rule isn’t firing, open a second terminal and run udevadm monitor. It’s like a real-time log of every hardware event hitting your kernel. You’ll see exactly where the matching process is failing.

3. Use Groups, Not 0666

Setting permissions to 0666 is a security risk—it lets any local user or compromised service access your hardware. Instead, assign the device to a specific group:

SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", GROUP="developer", MODE="0660"

This ensures only users in the developer group can touch the device, keeping your production environment much tighter.

Udev might look intimidating with its double-equals and curly braces, but it is one of the most reliable parts of the Linux stack. It transforms a chaotic mess of hot-swappable hardware into a predictable, automated system. Start with one simple symlink, and you’ll never go back to chasing shifting device names again.

Share: