I want to name a (USB) device persistently depending on the port it is connected to.

Using udevadmin I found the following info

# udevadm info --name=input/event3 | grep ID_PATH
E: ID_PATH=platform-ci_hdrc.1-usb-0:1.1.4:1.0
E: ID_PATH_TAG=platform-ci_hdrc_1-usb-0_1_1_4_1_0

So the device seems to have properties ID_PATH and ID_PATH_TAG, which look like what I want.

I added to a matching udev.rule

SYMLINK+="foo-%E{ID_PATH_TAG} foo1-$env{ID_PATH} foo2-$env{ID_PATH_TAG}"

(The 3 variants were just trying desperately... one should be enough once it works.)

The rule gets executed and the there is no error in the log (log level = debug).

However, the created symbolic links are called


So it looks like the properties ID_PATH and ID_PATH_TAG are not yet set when my rule gets executed. Do I need to pay attention to any ordering?


2 Answers 2


First run this command to get the list of attributes of your device.

udevadm info -a -p $(udevadm info -q path -n <devpath>)

then you can do something like this

... SYMLINK+=”device_$attr{serial}”, ...

sometimes you have to set a environment variable with the data that you need, something like this.

... ENV{SERIAL_NUMBER}="$attr{serial_number}"

to later use it like this.

... SYMLINK+="device_$env{SERIAL_NUMBER}"
  • What is exactly the difference between an environment variable and an attribute? If there is an attribute, why would I want to set an environment variable first and then use it later instead of just using the attribute in the first place? My udevadm info output showed E:, so I'm guessing ID_PATH is an environment variable.
    – Uwe Geuder
    Commented Sep 22, 2015 at 6:04

I saw that existing rules using ID_PATH are all 60-* or higher. Mine was 45-* for no particular except historic reasons.

Renaming my rules file shows that it's the rule number that makes the difference:

  1. 59-foo.rules: ID_PATH/ID_PATH_TAG expand to empty string
  2. 60-foo.rules: ID_PATH/ID_PATH_TAG expand to empty string
  3. 61-foo.rules: ID_PATH/ID_PATH_TAG expand correctly

The explanation is in 60-persistent-input.rules containing

SUBSYSTEMS=="pci|usb|platform|acpi", IMPORT{builtin}="path_id"

I could not find documentation for the builtins, but I'm guessing that the path_id builtin puts ID_PATH/ID_PATH_TAG into the environment.

  • You can also bring in the path's by adding this just above the SUBSYSTEMS line: ENV{ID_PATH}=="", IMPORT{builtin}="path_id"
    – joshperry
    Commented Oct 17, 2017 at 3:31
  • Yeah it sounds logical that that should work. However, I would not see a good reason to duplicate that code into my own "earlier" rule, if the distro already contains the same code in a "later" rule.
    – Uwe Geuder
    Commented Oct 17, 2017 at 23:07
  • Agreed. FYI, saw this technique here: lists.debian.org/debian-user/2017/07/msg01453.html
    – joshperry
    Commented Oct 19, 2017 at 3:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .