How to create files in the `/etc/udev/rules.d/` directory?

There is a software that needs to check whether the specified file in this directory exists. I know that you can use services.udev.extraRules to add new rule content, but it can’t generate the file I need, so it can’t achieve the goal.

Try to use environment.etc."udev/rules.d/99-steelseries-rival.rules".text = ... to generate this file, but it still fails. This method will cause permission problems: ln: failed to create symbolic link'/nix/store/10snfh4rgdifz7jzda7j33q24jri743s-etc/etc/udev/rules.d/99-steelseries-rival.rules': Permission denied.

Note: I used sudo to run the nixos-rebuild switch command.

1 Like

okay, I had a play with this, and your right, it seems that udev files cannot be added in this way. :-(. This looks like it’s by design

However i see in nixpkgs/blob/nixos-20.09/nixos/modules/services/hardware/udev.nix

a bit of bash

      # Add the udev rules from other packages.
      for i in $packages; do
        echo "Adding rules for package $i"
        for j in $i/{etc,lib}/udev/rules.d/*; do
          echo "Copying $j to $out/$(basename $j)"
          cat $j > $out/$(basename $j)

which i think is wired to

    services.udev = {

      packages = mkOption {
        type = types.listOf types.path;
        default = [];
        description = ''
          List of packages containing <command>udev</command> rules.
          All files found in
          <filename><replaceable>pkg</replaceable>/etc/udev/rules.d</filename> and
          will be included.
        apply = map getBin;

this seens to copy udev rules from nix/OS packages.

This has a down side that you will need to create a package, which contains your udev file then

sevices.udev.package = [ mypackage ];

this examples may help

  services.udev.packages = with pkgs; [

if you check out


you can see

which you may be able to adapt to your own package.

If you get stuck i can probably hacksome thing together for you if i have time… !

There maybe an easier way to do this…

1 Like

You can create single file packages using trivial builders. For example:

writeTextFile {
  name = "my-udev-package";
  text = ''
  destination = "/lib/udev/rules.d/20-ledger.rules";

very nice!!!

Hey @jtojnar,

thank you for this hint. I still have problems seeing the whole picture, for adding the writeTextFile package to the services.udev.packages option.

I tried the following:

services.udev.packages = [
    pkgs.writeTextFile {
      name = "wally_udev";
      text = ''

      destination = "/etc/udev/rules.d/50-wally.rules";

However I get the following error:

building Nix...
building the system configuration...
error: A definition for option `services.udev.packages.[definition 2-entry 1]' is not of type `path'. Definition values:
- In `/home/tim/.dotfiles/system/configuration.nix': <function, args: {checkPhase?, destination?, executable?, name, text}>
(use '--show-trace' to show detailed location information)

Can you tell whats still wrong with how I apply this?

You are missing parentheses around the list item so you are adding two separate items: pkgs.writeTextFile function and the attribute set.

Indeed! I am obviously new to nix - works like a charm now! Thank you very much!

1 Like