5

I'm running RHEL6 and I'm trying to write a udev rule that is triggered upon plugging in and removing usb devices. I created a file called 80-usb.rules in /etc/udev/rules.d/ and I gave it the following contents (so far nothing too specific, just want to test):

ACTION=="add", SUBSYSTEMS=="usb", RUN+="touch /tmp/test"

I saved the file and plugged in a USB drive to test. However, the file /tmp/test was not created.

I figure my udev rule should match my USB drive, since I can run udevadm info on the USB drive and at least one of the parent devices has the attribute SUBSYSTEMS=="usb".

Why might the udev rule not get triggered?

I tried to run udevadm test --action=add /path/to/device and it is clear that the .rules file that I wrote is being processed and that my rules are being matched. Here are a few relevant lines from the output:

parse_file: reading '/etc/udev/rules.d/80-usb.rules' as rules file
udev_rules_apply_to_event: RUN '/bin/touch /tmp/test' /etc/udev/rules.d/80-usb.rules:1
udevadm_test: run: '/bin/touch /tmp/test'

But still, /tmp/test does not exist. I am so confused. Clearly this rule is being matched and the rules are being applied. So why doesn't the command specified by RUN execute?

  • 1
    Have you restarted udev after adding the 80-usb.rules file? systemctl restart udev.service – drs Apr 23 '13 at 2:08
  • Have you tried making a script that executes the touch command and setting RUN to the path to the script? – drs Apr 23 '13 at 2:18
  • 2
    The rule might have write permissions to write in /, but if you are not sure about that, at least while experimenting you should touch /tmp/udevfile – Anthon Apr 23 '13 at 4:11
  • Thanks for the help guys, but none of your suggestions got me closer to a solution, unfortunately. udev isn't actually a service on my machine (udev-post is, but restarting that won't and doesn't help any). Writing to /tmp/ is a good idea though. I don't know why I wasn't writing there before. Brain fart, I guess. – jayhendren Apr 23 '13 at 15:59
  • 1
    Thanks Gilles. I'm at a total loss here. When I run udevadm monitor I can clearly see the add and remove events when I plug/unplug my USB stick. But when I put the udev event attributes found using this method into a udev rule, I cannot get the rule to trigger and the command specified with RUN+="..." to run. I've even tried manually triggering with udevadm trigger. – jayhendren Apr 24 '13 at 5:55
2

Your rule must give an absolute path for executable:

ACTION=="add", SUBSYSTEMS=="usb", RUN+="/usr/bin/touch /tmp/test"

Edit:

And if you want to execute a script, you must tell what shell will execute it:

ACTION=="add", SUBSYSTEMS=="usb", RUN+="/bin/sh /path/to/your/script"
  • Hmm, I don't think that's the issue. touch resolves to /bin/touch according to the posted debug output. What's your source for "Your rule must give an absolute path for executable"? – jayhendren Jan 4 '16 at 18:36
  • 1
    freedesktop.org/software/systemd/man/udev.html "Execute an external program specified as the assigned value. If no absolute path is given, the program is expected to live in /usr/lib/udev; otherwise, the absolute path must be specified." – Mathieu Jan 4 '16 at 19:53
  • 1
    Ah. The man page you linked to appears to come from systemd, but the question specifically asks about RHEL 6, which does not have systemd. I checked the man page for udev on RHEL 6, and no dependency on an absolute path to a program is given there. – jayhendren Jan 4 '16 at 21:41
  • Thanks for pointing out the path and env issue. My script was missing the #!/bin/bash at the beginning of the same ant that was the issue. – rkachach May 20 '19 at 15:39
1

You have to ensure the following:

  • Paths in the RUN command should be absolute
  • The file has to be executable
  • The PATH environment is limited within the execution of you command

At first add this script file to /lib/udev/touch.sh

vim /lib/udev/touch.sh

in that file write:

#!/bin/bash
touch /tmp/test

make it executable:

chmod +x /lib/udev/touch.sh

and change your rules file to:

ACTION=="add", SUBSYSTEMS=="usb", RUN+="/lib/udev/touch.sh"

reload your udev rules

udevadm control --reload-rules

This will read your rules in /lib/udev/rules.d/* again. Changes will not apply until now.

Note that udev executes your script with a reduced PATH environment. You have to ensure that any binary that's not within the configured paths has to be accessed with a full path. You could also extend the PATH environment within your script.

Check what path is defined by logging the set output to a log file from your wrapper script:

set >>/tmp/udev-env-test

It might look like this:

PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  • 1
    it just can run the script not a command – mohammad Nov 6 '13 at 13:43

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.