Use UUID in udev rules and mount usb drive on /media/$UUID

Even though UUIDs are not directly accessible by udev, at least in Fedora and Ubuntu they are set as environment variables (ENV). You can read out all environment variables of a device by calling udevadm info /dev/sdc. E.g. for an NTFS on an external drive I get:

$ udevadm info /dev/sdc2
P: /devices/pci0000:00/0000:00:14.0/usb4/4-2/4-2:1.0/host7/target7:0:0/7:0:0:0/block/sdc/sdc2
N: sdc2
[…]
E: ID_FS_TYPE=ntfs
E: ID_FS_USAGE=filesystem
E: ID_FS_UUID=4A6F2ABC1232FA37
[…]

Everything with an E: in front is set as an environment variable.

Matching against UUIDs

You can match against it with ENV{ID_FS_UUID}=="4A6F2ABC1232FA37". As a first filter I match against KERNEL=="sd?2" to make sure I'm only handling block devices with the correct partition number. The complete rule would look like this:

KERNEL=="sd?2", ENV{ID_FS_UUID}=="4A6F2ABC1232FA37", RUN+="/usr/bin/logger --tag my-manual-usb-mount Mounting the device with UUID 4A6F2ABC1232FA37", RUN+="/usr/bin/mount [Your mount options here]"

The logger command is useful to assert that the rule is actually run. Next you should check that the rule does not contain any syntax errors with udevadm test /dev/sdc2. Your rules file should be listed in the output and no error message should appear next to it. Now you can trigger all rules for your device to check whether your rule works as planned: sudo udevadm trigger /dev/sdc2. If your rule matched you will find the custom log message in the system log (/var/log/syslog or via journalctl -b).

Edit: ali_m has pointed out that the environment variables are set by previous rules and thus only accessibly if your .rules file has a sufficiently high lexicographical ordering. Starting with "60" should be enough. Personally I start my rules with "zz" (if possible) to distinguish them from predefined rules in a glance.

Using UUIDs in the RUN command and elsewhere

Udev has a quite powerful variable and attribute substitution syntax. Specifically every occurrence of $env{ID_FS_UUID} will be replaced with the UUID of the drive. So to mount a device under /media/UUID you could use this rule:

KERNEL=="sd??", RUN+="/usr/bin/mkdir /media/$env{ID_FS_UUID}", RUN+="/usr/bin/mount $devpath /media/$env{ID_FS_UUID}"

You probably want to configure udisks instead, though, it is specialized for the problem space you want to solve. See https://wiki.archlinux.org/index.php/udisks#udisks2:_mount_to_.2Fmedia as a starting point.

My actual use case for mounting devices with udev instead of /etc/fstab or udisks is to mount zfs file systems which have some idiosyncrasies making them not quite fit the usual tools.