I need to perform a command when I connect a bluetooth keyboard. How can I 'listen' this event?
2 Answers
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.
- 1While your answer looks excellent I've had no luck getting it to work :( here are my inputs/outputs: gist.github.com/vemv/5275029deprecated– deprecated2013-03-30 02:28:12 +00:00Commented Mar 30, 2013 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'– Gilles 'SO- stop being evil'2013-03-30 02:37:08 +00:00Commented Mar 30, 2013 at 2:37 - All the files listed when running
udevadm test class/input/event9start with two digits. Could that have something to do?deprecated– deprecated2013-03-30 02:40:31 +00:00Commented Mar 30, 2013 at 2:40 - @vemv No, that's not a problem, and the output from
udevadm testshows 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'– Gilles 'SO- stop being evil'2013-03-30 02:43:06 +00:00Commented Mar 30, 2013 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– Bananguin2013-03-30 19:18:13 +00:00Commented Mar 30, 2013 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.
- 3There 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– Bananguin2013-03-29 23:22:34 +00:00Commented Mar 29, 2013 at 23:22 - Thanks for the heads up! Sounds like your pointer is going to save me a lot of work :)deprecated– deprecated2013-03-29 23:30:48 +00:00Commented Mar 29, 2013 at 23:30