Wed, 21 Feb 2007
Device Event Handler
An useless but nice hack of the day:
I have explored the udev
rules a bit further - with udev
, it is possible even to run a script when the device is created.
I wrote two simple scripts - one at home, where it loads images from
my camera after I plug the camera in, and stores them into my image repository.
The other at work - around 6:30pm, I download the main daily news from the
Czech radio station Radiožurnál, encode it to OGG/Vorbis, and when my Palm
is plugged in, the script started by udev
copies the audio file
to the Palm. The rule itself is pretty simple:
$ cat /etc/udev/rules.d/60-palm-news.rules KERNEL=="sd*1", SYSFS{serial}=="50xxxxxxxxxxxxxxxxxxxx39", \ SYSFS{product}=="palmOne Handheld", \ SYSFS{manufacturer}=="palmOne, Inc.", \ RUN+="/usr/local/sbin/news-to-palm"
The tricky part was to not interchange double "==" with the single "="
by accident, and using the "KERNEL
" parameter (otherwise,
the script would be run for every virtual device along the path
(USB device, virtual SCSI controller of the mass storage device,
the whole USB disk, and finally every partition on that disk).
Another tricky part is to use device nodes from /dev/disk/by-uuid
in the mount(8)
command, so that the device path remains the same
no matter which USB port I plug my PDA into, or what other mass storage
devices are currently plugged in.
As an user-friendly bonus, the "news-to-palm
" script
uses notify-send
to send a completion message over
D-bus
to inform me that I can unplug the PDA.
Update - Thu, 22 Feb 2007: More details
I forgot to mention some important tips:
- Sending a notification is done with the following command:
su kas -c 'DISPLAY=:0 notify-send "News" "News copied to Palm."'
This of course requires that the notification is being sent to user "kas
", logged in at the ":0
" display. In theory it should be possible to send the notification over the system d-bus (dbus-0
), but I did not found a suitable parameter fornotify-send(1)
. - The parameters for the udev rule are easy to find. Just plug the device
in, find (looking at the
dmesg(8)
output) the name of the special file the device currently uses (for example,/dev/sdb
), and run the following command:$ udevinfo -a -p `udevinfo -q path -n /dev/sdb`
You can use theSYSFS{}
parameters not only from the leaf (top-most) node, but from all nodes along the path.