How to use uutils-coreutils instead of the builtin coreutils?

I just installed the uutils-coreutils package but it gives me prefixed binaries like uutils-cp instead of just cp. I’m trying to live on the edge and use uutils-coreutils instead of any built-ins. Is there a way to do this, preferably home-manager-friendly?

It looks like there’s indeed an option for this: https://github.com/NixOS/nixpkgs-channels/blob/c59ea8b8a0e7f927e7291c14ea6cd1bd3a16ff38/pkgs/tools/misc/uutils-coreutils/default.nix#L21. It’s just not clear to me how to adjust prefix from within home-manager. Does anyone know how to do this?

Usually when you want to live on the edge, its best not to ask for a complete solution but mention the steps you’ve taken and where you’re stuck.

When you add the package you need to override the prefix argument. Set it null or whatever you want.

1 Like

Gotcha, I’m not having much success with .override and .overrideAttrs unfortunately:

home.packages = [
    pkgs.uutils-coreutils.override { prefix = ""; }
];

gives me an error:

❯ home-manager switch             
error: The option value `home.packages.[definition 16-entry 10]' in `/home/skainswo/.config/nixpkgs/home.nix' is not of type `package'.
1 Like

You need brackets:

home.packages = [
    (pkgs.uutils-coreutils.override { prefix = ""; })
];
3 Likes

Awesome, thanks @Ninlives! That did the trick.

For anyone finding this thread in the future: Now there is also uutils-coreutils-noprefix

4 Likes

Sorry for reviving this old thread, but can someone offer an explanation on how uutils-coreutils-noprefix does this in nixpkgs? I want to override coreutils to wrap the rm command to be safe-rm, but using an overlay causes NixOS to try to rebuild basically all the packages(and ultimately fails).
Simply adding the β€œnoprefix” version of uutils-coreutils to environment.systemPackages seems to change all the coreutils binaries without prompting a system wide rebuilds. I’m tempted to just override and use these coreutils instead, but rust is well known for taking a while to build

I feel a little stupid now, instead of overriding the actual coreutils package, I could just make make build my own, and adding it in environment.systemPackages did the trick.

this would cause everything to be rebuild:

      nixpkgs = {
        # You can add overlays here
        overlays = [
          (final: prev: {
            coreutils = prev.coreutils.overrideAttrs (oldAttrs: rec {
              postInstall = ''
                mv $out/bin/rm $out/bin/rm.bak
                ln -s ${pkgs.unstable.rmtrash}/bin/rmtrash $out/bin/rm
              '';
            });
          })
        ];
      };

so instead, this worked:

      nixpkgs = {
        # You can add overlays here
        overlays = [
          (final: prev: {
            myCoreutils = prev.coreutils.overrideAttrs (oldAttrs: rec {
              postInstall = ''
                mv $out/bin/rm $out/bin/rm.bak
                ln -s ${pkgs.unstable.rmtrash}/bin/rmtrash $out/bin/rm
              '';
            });
          })
        ];
      };

      environment.systemPackages = with pkgs; [ 
        myCoreutils
      ];

But this is better, to just copy the output of coreutils and not need to rebuild it:

      nixpkgs = {
        # You can add overlays here
        overlays = [
          (final: prev: {
            myCoreutils = pkgs.symlinkJoin {
                name = "coreutils-wrapped";
                paths = [ pkgs.coreutils ];
                nativeBuildInputs = [ ];
                postBuild = ''
                  rm $out/bin/rm
                  ln -s ${pkgs.rmtrash}/bin/rmtrash $out/bin/rm
                '';
              };
            })
        ];
      };

      environment.systemPackages = with pkgs; [ 
        myCoreutils
      ];
2 Likes

What is currently the best option to replace coreutils with uutils-coreutils-noprefix? Just installing the package didn’t’t do the trick for me. Still, the default coreutils are used.

I don’t think desktop-common: use uutils-coreutils Β· pbek/nixcfg@1e82090 Β· GitHub is the best way to do it. :blush:

The best option? Don’t.

Because they are not stable enough?

Here’s how: common/system: switch to `uutils-coreutils` Β· drupol/nixos-x260@454d217 Β· GitHub

1 Like

That’s not really β€œswitching” as much as it is introducing a conflicting package that may or may not take precedence. At least use lib.hiPrio if you’re going to do that.

But again, it’s not a good idea to just drop in a random replacement if you’re not prepared to deal with breakage.

Actually, just doing that works pretty fine, I don’t really understand why I would change it. Can you tell me more about the conflicting package? I don’t have any conflicting issue at the moment.

Let’s put aside the righteousness of this original question and focus on how to do it properly, please. I guess people willing to do that knows what they are exposing themselves to if it is breaking their systems.

1 Like

It would obviously conflict with coreutils-full:

which is unsurprising, since that’s what you’re trying to replace in the first place.

I haven’t seen anything related to any conflict while doing that:

...
nixos-system-x13-25.05.20250129.9d3ae> building '/nix/store/6pp7d5fsqw6ns2hfbyiygj4cp142bp51-nixos-system-x13-25.05.20250129.9d3ae80.drv'
┏━ Dependency Graph:
┃       β”Œβ”€ βœ” xdg-desktop-portal-1.18.4_fish-completions 
┃       β”œβ”€ βœ” uutils-coreutils-0.0.29_fish-completions 
┃       β”œβ”€ βœ” xf86-input-evdev-2.11.0_fish-completions 
┃       β”œβ”€ βœ” xf86-input-libinput-1.5.0_fish-completions 
┃       β”œβ”€ βœ” xwaylandvideobridge-0.4.0_fish-completions 
┃    β”Œβ”€ βœ” system_fish-completions 
┃    β”‚  β”Œβ”€ βœ” unit-dbus.service 
┃    β”œβ”€ βœ” user-units 
┃    β”‚  β”Œβ”€ βœ” unit-accounts-daemon.service 
┃    β”‚  β”‚  β”Œβ”€ βœ” X-Restart-Triggers-polkit 
┃    β”‚  β”œβ”€ βœ” unit-polkit.service 
┃    β”‚  β”‚        β”Œβ”€ βœ” system-path ⏱ 14s
┃    β”‚  β”‚     β”Œβ”€ βœ” dbus-1 
┃    β”‚  β”‚  β”Œβ”€ βœ” X-Restart-Triggers-dbus 
┃    β”‚  β”œβ”€ βœ” unit-dbus.service 
┃    β”œβ”€ βœ” system-units ⏱ 1s
┃    β”‚  β”Œβ”€ βœ” man-cache ⏱ 31s
┃    β”œβ”€ βœ” etc-man_db.conf 
┃ β”Œβ”€ βœ” etc 
┃ βœ” nixos-system-x13-25.05.20250129.9d3ae80 
┣━━━ Builds            β”‚ Downloads        β”‚ Host                            
┃        β”‚ βœ” 109 β”‚     β”‚     β”‚      β”‚     β”‚ localhost                       
┃        β”‚       β”‚     β”‚     β”‚ ↓ 34 β”‚     β”‚ https://cache.nixos.org         
┗━ βˆ‘ ⏡ 0 β”‚ βœ” 109 β”‚ ⏸ 0 β”‚ ↓ 0 β”‚ ↓ 34 β”‚ ⏸ 0 β”‚ Finished at 17:18:49 after 1m24s
> Comparing changes
<<< /run/current-system
>>> /tmp/nh-osbTTLJD/result
Added packages:
[A+]  #1  uutils-coreutils  0.0.29, 0.0.29_fish-completions
Closure size: 2381 -> 2383 (17 paths added, 15 paths removed, delta +2, disk usage +14.3MiB).
> Activating configuration
stopping the following units: accounts-daemon.service
activating the configuration...
setting up /etc...
reloading user units for pol...
restarting sysinit-reactivation.target
reloading the following units: dbus.service
restarting the following units: polkit.service
starting the following units: accounts-daemon.service
the following new units were started: NetworkManager-dispatcher.service
> Adding configuration to bootloader
❯

That makes no sense… They have the identically-named binaries in $out/bin, if they don’t conflict that’s a bug.

EDIT: On that note, I found a funny behavior:

# shell.nix
with (import <nixpkgs> {};);
mkShell {
  packages = [
    coreutils-full
    uutils-coreutils-noprefix
  ];
}

Running shell.nix produces no errors, but which -a wc results in

$ which -a wc
/nix/store/imrcr31vjr7p62lgqh3k9p4j3vz1y5yf-coreutils-full-9.5/bin/wc
/nix/store/l9qw6fypp48vmsypha9g6rfpbhksyf6k-uutils-coreutils-0.0.29/bin/wc
/nix/store/pw26z7msfmv291jq1qpp8bbaprs5hkfk-coreutils-9.5/bin/wc
/nix/store/pw26z7msfmv291jq1qpp8bbaprs5hkfk-coreutils-9.5/bin/wc
/run/current-system/sw/bin/wc

Which shows that the uutils versions are getting silently masked. I didn’t test it with a full NixOS configuration, but I wouldn’t be surprised if there’s some screwy thing happening here. Either way, your example would be incorrect.

I’ve set lib.hiPrio, and I still don’t have the same result as you.

❯ which -a wc
/run/current-system/sw/bin/wc
❯ wc --version
wc 0.0.29