Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass ATTR{idVendor} as argument in udev script

I have a script which is run whenever a usb device by vendor 1004 is connected. The udev rule I am using works and looks like this.

SUBSYSTEM=="usb", ATTR{idVendor}=="1004", RUN+="/var/www/beta/trigger.php"

Now I would like to have this script run whenever ANY usb device is connected, and pass the Vendor ID as parameter. (So the script can decide whether it has to be run or not.)

Adding a parameter which can be accessed in the script has worked so far:

SUBSYSTEM=="usb", RUN+="/var/www/beta/trigger.php myparam"

Can someone please tell me how to replace "myparam" with the value of ATTR{idVendor}? I have tried all kinds of combinations, but I never got the expected result...

Thanks a lot!

like image 684
joshtucker Avatar asked Oct 10 '12 12:10

joshtucker


People also ask

Is it possible to run programs inside of udev rules?

Note that running programs that access the network or mount/unmount filesystems is not allowed inside of udev rules, due to the default sandbox that is enforced on systemd-udevd.service. Thanks for contributing an answer to Unix & Linux Stack Exchange! Please be sure to answer the question.

What is udev in Linux?

Learn Basics of Udev in Linux The udev daemon, systemd-udevd (or systemd-udevd.service) communicates with the kernel and receives device uevents directly from it each time you add or remove a device from the system, or a device changes its state. Udev is based on rules – it’s rules are flexible and very powerful.

How to match attR and env on same device?

Search the devpath upwards for a device with matching sysfs attribute values. If multiple ATTRS matches are specified, all of them must match on the same device. Match against a device property value. If both ENV and ATTR contain the same information - you can use any of them, there is no any difference.

What are the pros and cons of udev?

One of the pros of udev is that it can use persistent device names to guarantee consistent naming of devices across reboots, despite their order of discovery. This feature is useful because the kernel simply assigns unpredictable device names based on the order of discovery.


2 Answers

Just to add on to this answer, udev also lets you pass arguments to RUN and PROGRAM.

From the udev man page:

   The NAME, SYMLINK, PROGRAM, OWNER, GROUP, MODE and RUN fields support simple
   printf-like string substitutions. The RUN format chars gets applied after
   all rules have been processed, right before the program is executed. It
   allows the use of device properties set by earlier matching rules. For all
   other fields, substitutions are applied while the individual rule is being
   processed.

For example, you could have a rule like this:

# Passes major, minor and serial number as parameters to script.
ACTION=="add", SUBSYSTEM=="usb", RUN+="/tmp/test.sh %M %m $attr{serial}"

The available substitutions are:

    $kernel, %k
       The kernel name for this device.

   $number, %n
       The kernel number for this device. For example, ´sda3´ has kernel number
       of ´3´

   $devpath, %p
       The devpath of the device.

   $id, %b
       The name of the device matched while searching the devpath upwards for
       SUBSYSTEMS, KERNELS, DRIVERS and ATTRS.

   $driver
       The driver name of the device matched while searching the devpath
       upwards for SUBSYSTEMS, KERNELS, DRIVERS and ATTRS.

   $attr{file}, %s{file}
       The value of a sysfs attribute found at the device, where all keys of
       the rule have matched. If the matching device does not have such an
       attribute, follow the chain of parent devices and use the value of the
       first attribute that matches. If the attribute is a symlink, the last
       element of the symlink target is returned as the value.

   $env{key}, %E{key}
       A device property value.

   $major, %M
       The kernel major number for the device.

   $minor, %m
       The kernel minor number for the device.

   $result, %c
       The string returned by the external program requested with PROGRAM. A
       single part of the string, separated by a space character may be
       selected by specifying the part number as an attribute: %c{N}. If
       the number is followed by the ´+´ char this part plus all remaining
       parts of the result string are substituted: %c{N+}

   $parent, %P
       The node name of the parent device.

   $name
       The current name of the device node. If not changed by a rule, it
       is the name of the kernel device.

   $links
       The current list of symlinks, separated by a space character. The
       value is only set if an earlier rule assigned a value, or during a
       remove events.

   $root, %r
       The udev_root value.

   $sys, %S
       The sysfs mount point.

   $tempnode, %N
       The name of a created temporary device node to provide access to the
       device from a external program before the real node is created.

   %%
       The ´%´ character itself.

   $$
       The ´$´ character itself.
like image 130
Kevin S Avatar answered Sep 29 '22 23:09

Kevin S


udev sets for you several environmental variables that you can use, among others ID_VENDOR. Try that little script:

#!/bin/bash

echo "Called by udev" >> /tmp/testenv
env >> /tmp/testenv
echo "Vendor id is $ID_VENDOR" >> /tmp/testenv

Put it in a rule, and you will see how much things are set up for you.

like image 30
January Avatar answered Sep 29 '22 21:09

January