4

I created a udev rule to execute a bash script after the insertion of a usb device

SUBSYSTEMS=="usb", ATTRS{serial}=="00000000", SYMLINK+="Kingston", RUN+="/bin/flashled.sh"

However the script is run several times instead of just once, I assume it is down to way the hardware is detected? I tried putting sleep 10 into the script and fi but it makes no difference.

Lurch
  • 819
  • 3
  • 18
  • 30
  • Is it running once for each device in the USB chain? i.e. if there are four parent devices/hubs, does it run four times? – rm5248 Nov 12 '13 at 19:04
  • I see you're appending to the `RUN` list - is it possible you did that multiple times? – Mark Reed Nov 12 '13 at 19:04
  • no to either of these questions, I found this post http://ubuntuforums.org/showthread.php?t=1747496 but not sure how it relates to my udev rule – Lurch Nov 12 '13 at 19:30

2 Answers2

2

I believe this may be down to the use of the pluralised SUBSYSTEMS and ATTRS keys. My understanding of udev is that those keys will match parent devices (see the "Device hierarchy" section of http://www.reactivated.net/writing_udev_rules.html#hierarchy). Try using SUBSYSTEM and ATTR to match just that device.

Callum Gare
  • 131
  • 2
  • 6
0

This is not a solution but a workaround:
One way (simple) is to begin your script "/bin/flashled.sh" like this

#!/bin/bash
#this file is /bin/flashled.sh

#let's exit if another instance is already running
if [[ $(pgrep -c "$0" ) -gt 1 ]]; then exit ;fi

... ... ...

However, this can in some border cases be a bit prone to race conditions (bash is a bit slow so there is no way to be sure that this will always work) but it might work perfectly in your case.

Another one (more solid but more code) is to begin "/bin/flashled.sh" like this:

#!/bin/bash
#this file is /bin/flashled.sh
#write in your /etc/rc.local: /bin/flashled.sh & ; disown
#or let it start by init.    

while :
do
    kill -SIGSTOP $$ # halt and wait
    ... ...          # your commands here
    sleep $TIME      # choose your own value here instead of $TIME
done

Start it during boot (by, for example, /etc/rc.local) so it will be waiting for a signal to continue... It doesn't matter how many "continue" signals it gets (they are not queued), as long as they are within $TIME

Change your udev rule accordingly :

SUBSYSTEMS=="usb", ATTRS{serial}=="00000000", SYMLINK+="Kingston", RUN+="/usr/bin/pkill -SIGCONT flashled.sh"
thom
  • 2,294
  • 12
  • 9