Writing udev Rules on Linux with AI Assistance
udev rules control how Linux names and reacts to devices, and the syntax is unforgiving. Here's how to inspect attributes and let AI draft rules you can verify.
- #linux
- #udev
- #devices
- #kernel
- #automation
udev is one of those subsystems you ignore for years until a USB serial adapter shows up as /dev/ttyUSB1 one boot and /dev/ttyUSB0 the next, and suddenly your data-acquisition script is reading the wrong device. Writing a udev rule to pin a stable name is conceptually simple and syntactically brutal — the difference between == and =, ATTR and ATTRS, KERNEL and SUBSYSTEM will silently break a rule with no error. This is precisely the kind of fiddly, well-documented-but-unmemorable task where an AI assistant shines as a fast junior engineer: it knows the grammar, drafts the rule, and explains each token, while I verify and own the result. Here’s the loop I use.
Finding the device and its attributes
Every udev rule is built from device attributes, so step one is always to enumerate them. udevadm info walks the device tree from a given node up through its parents.
udevadm info --name=/dev/ttyUSB0 --attribute-walk
This dumps every ATTRS{...}, KERNELS, and SUBSYSTEMS value at each level of the hierarchy. It’s verbose and a little overwhelming, which makes it perfect to hand to an AI: paste the walk and ask it to identify the most stable, unique attributes to match on (typically idVendor, idProduct, and a serial number).
Pro Tip: Match on the fewest attributes that still uniquely identify the device, and prefer a serial number when one exists. Over-matching on a USB port path means your rule breaks the moment someone moves the cable to a different port.
Drafting the rule with AI
Now I describe what I want in English. A prompt I reuse:
“From this udevadm attribute walk, write a udev rule that creates a stable symlink
/dev/sensor0for this device, matching on idVendor, idProduct, and the serial. Explain each field so I can verify it.”
The model produces something like:
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A50285BI", SYMLINK+="sensor0", MODE="0660", GROUP="dialout"
and, crucially, explains why it’s ATTRS (matching a parent device) rather than ATTR (the device itself), and why SYMLINK+= appends rather than replaces. That explanation is what lets me actually verify the rule instead of cargo-culting it. I save the good prompts in a shared prompt library so the rule style stays consistent across the team.
Testing before you reload
Never drop a rule into production and reboot to find out if it works. udev has a test mode that simulates rule processing against a real device without applying anything.
udevadm test $(udevadm info --query=path --name=/dev/ttyUSB0) 2>&1 | less
This shows exactly which rules matched and what actions they’d take. When the output is confusing, paste it back to the AI — it’s good at spotting that your rule didn’t fire because you used KERNEL instead of KERNELS, a one-character bug that produces zero error messages.
Installing and reloading
Rules live in /etc/udev/rules.d/ and are processed in lexical order, so the numeric prefix matters.
sudo tee /etc/udev/rules.d/99-sensor.rules <<'EOF'
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A50285BI", SYMLINK+="sensor0", MODE="0660", GROUP="dialout"
EOF
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=tty
--reload-rules re-reads the files; trigger re-emits events so the rule applies to already-connected devices without a reboot. Verify the symlink appeared:
ls -l /dev/sensor0
Running a script on device events
udev can also launch actions, which is where people get into trouble. You can call a script with RUN+=, but udev runs it in a tightly constrained, short-lived context — long-running work belongs in a systemd unit triggered by the device, not inline.
SUBSYSTEM=="net", ACTION=="add", ATTRS{idVendor}=="0bda", TAG+="systemd", ENV{SYSTEMD_WANTS}="usb-nic-setup.service"
Ask the AI to explain the TAG+="systemd" / SYSTEMD_WANTS pattern; it’s the correct, modern way to bridge a device event to a real service, and it’ll steer you away from blocking the udev worker. This is the kind of architectural nudge a good copilot gives that saves you a self-inflicted outage.
Debugging a rule that won’t fire
The most maddening udev failure is silence: your rule is installed, the device is plugged in, and nothing happens. There’s no error because udev rules don’t raise errors — a non-matching rule simply does nothing. The way in is to monitor events live as you plug the device.
udevadm monitor --environment --udev
# now unplug and replug the device in another terminal
This streams every uevent with its full environment, so you see exactly what SUBSYSTEM, ACTION, and attributes the kernel actually emitted — which is often subtly different from what you matched on. Capture a chunk of that output and hand it to the AI:
“Here’s udevadm monitor output for a device, and here’s my rule that isn’t firing. Tell me which match key in my rule doesn’t line up with the actual event.”
It’s excellent at this kind of diff — it’ll spot that you matched ACTION=="add" but the relevant event is ACTION=="change", or that you used the device’s own ATTR when the value lives on a parent and needs ATTRS. That single-character class of bug is hard for a human to see and easy for a model that’s comparing two structured blocks side by side.
Pro Tip: Match on ACTION deliberately. Many USB and block devices emit change events as well as add, and a rule scoped to add only will quietly miss half the lifecycle. When in doubt, watch udevadm monitor and match what the kernel actually sends.
Persisting network interface names
A common real-world use is pinning a NIC’s name so it doesn’t shuffle between eth0 and eth1 across reboots.
udevadm info /sys/class/net/eth0 | grep -E 'ID_NET_NAME|address'
Grab the MAC, then have the AI draft a rule that renames the interface based on it. It knows the NAME= assignment has to happen in the net subsystem on the add action and will produce a rule that survives reboots — a small but high-value bit of stability for servers with multiple NICs.
Keeping it safe
The rules here are low-risk to draft with AI because they’re declarative and you test them with udevadm test before applying. But the safety discipline still holds: the AI drafts and explains, you verify every match key against the real attribute walk, and you never let it execute udevadm control against a production box on your behalf. It is a fast junior engineer that writes the first draft — the human reviews and runs it, and prod credentials never enter the chat. A wrong udev rule can rename or hide a device your platform depends on, so a human signs off every time. If you want device-event changes reviewed as part of your change process, our code-review dashboard keeps the reasoning attached to the rule.
Conclusion
udev rules went from a dreaded yak-shave to a ten-minute task once I let an AI handle the grammar I refuse to memorize. The recipe: walk the attributes, have the model draft and explain a minimal rule, test it with udevadm test, install it, and trigger. The human owns matching decisions and execution; the AI owns the syntax it knows cold. For more device and kernel-level guides see the Linux admin category, and the Linux admin prompt pack includes the udev-drafting prompts I rely on.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.