I need to perform a command when I connect a bluetooth keyboard. How can I 'listen' this event?


When a piece of hardware is plugged in, the udev framework decides what to do with it. A typical action is to create a device node under /dev, but you can run any shell command.

First, you need to figure out how to identify your device. Connect the keyboard and run udevadm info -a -n /dev/input/event9 where the last argument is the path to the device file in /dev/ corresponding to your device. You can omit the /dev/ prefix. You can use a syspath (a path under /sys) instead of a device node name by replacing -n … by -p class/input/event9. In all cases, replace input/event9 by the appropriate path for your device. This prints various characteristics of your device. Collect one or more of the lines of the form SETTING=="VALUE", enough to identify your device uniquely.

Create a file under /etc/udev/rules.d called vemv-keyboard.rules or some such. Put a line in this file with the settings to be matched and an action to run. Take care to use the proper operators: it's == for properties to be matched, = for properties to be set, and += to specify additional actions. Something like:

# Run a program when my wireless keyboard is connected
SUBSYSTEMS=="input", ATTRS{vendor}=="Yoyodene", ATTRS{model}=="Bluetooth keyboard 9000", RUN+="/path/to/script $root/$name"

The program will run the next time you plug the device in (adding the file has no effect on already-connected devices). You check that your rule would have the desired effect by running udevadm test class/input/event9 (where the argument is the syspath as above). If you want to apply the rule manually, run udevadm trigger --sysname=class/input/event9.

| improve this answer | |
  • While your answer looks excellent I've had no luck getting it to work :( here are my inputs/outputs: gist.github.com/vemv/5275029 – vemv Mar 30 '13 at 2:28
  • @vemv You need to use the absolute path of the script. I can't see why ATTRS{name}=="Apple Wireless Keyboard", RUN+="/home/vemv/bin/myscript" didn't work though. – Gilles 'SO- stop being evil' Mar 30 '13 at 2:37
  • All the files listed when running udevadm test class/input/event9 start with two digits. Could that have something to do? – vemv Mar 30 '13 at 2:40
  • @vemv No, that's not a problem, and the output from udevadm test shows that your rules were read. The rules files are read in lexicographic order, the ones that begin with a digit are read before the ones that begin with a letter. – Gilles 'SO- stop being evil' Mar 30 '13 at 2:43
  • Can you try to just RUN+="/path/to/a/script" without any arguments and see if you can get udev to actually run a script of yours? It shouldn't make any difference, but I recall having a hard time to make my rules work. I ended up doing some logic in my script, which udev could have done just as well. – Bananguin Mar 30 '13 at 19:18

Looks like running udevadm monitor is a good basis for solving my problem. One can have a daemon parsing its output, filtering the desired entries, and reacting to those events.

| improve this answer | |
  • 3
    There is such a daemon. It's called udevd. You configure it with "rules", which are stored in /etc/udev/. It comes with a man page too. – Bananguin Mar 29 '13 at 23:22
  • Thanks for the heads up! Sounds like your pointer is going to save me a lot of work :) – vemv Mar 29 '13 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.