Rust-based Coreutils — Installing official repository release and instantiating as replacement

:warning: Danger!

Coreutils is the some of the most critical software for personal computation on most Linux systems. While this mostly works, you can expect issues with some lacking binaries, and since this is the official Arch Linux repository release, whatever issues withstanding in it will persist until it is updated.

There are AUR releases of this, but the one which seems to look the best also doesn’t build at the moment. Whenever that is resolved, you should be able to swap the files out by following the provided instructions.

Known issues exist with incorrect flags defined in the provided file from uutils-coreutils which may or may not be resolved over time.

You agree that following this guidance is at your own peril. All fault from following these instructions for system malfunction or instability is on you.

Preface

If you’ve seen the news recently, Canonical made a big splash in the Linux space with Canonical proclaiming they wish to replace the GNU Coreutils which make up their GNU / Linux distribution by eliminating as much of, if not in-entirety Coreutils in favour for their rust-based alternative; Uutils.

Good fortune for us Arch users; we can implement use of this software at our own leisure, and with a basic understanding of the filesystem hierarchy most open-source system users swear as unwritten oath to abide by, do so safely.

Installation

This is pretty simple. In a terminal emulator of preference:

sudo pacman -S uutils-coreutils

Once that is finished, then the fun really begins. A brief look in /usr/bin with ls reveals a bunch of which begin with the character uu-. We’ll use this to take advantage of some inline scripting trickery for moving into the appropriate locations Arch Linux respects.

Instantiation

Because GNU’s coreutils is already installed, we’ll have to create our new replacement references elsewhere. All Uutils consists of from the Arch Linux package is a single binary; uu-coreutils with all functions defined as symbolic links. (Yes, that’s how it really works.)

Because of that, we can take advantage this naming schema to instantiate the links so they are placed in /usr/local/bin for use as coreutils’ successor, if desired.

Using multiple binaries already provided by GNU Coreutils, we can make what’s there usable:

:pencil2: You can elect to replace /usr/bin/uu-{} with /usr/bin/uu-coreutils for the same effect, but what’s shown here would be more difficult to follow if presented like that.
:test_tube: The hashsum symlink action might need some massaging; you may end up using tail instead of head depending on output. try without head and xargs first!

find /usr/bin -name 'uu-*' -type l -printf '%f\n' | cut -c 4- | xargs -I{} sudo ln -s /usr/bin/uu-{} /usr/local/bin/{}
find /usr/bin -name 'sha*sum' -printf '%f\n' | sort -g | head -n 5 | xargs -I{} sudo ln -s /usr/bin/uu-hashsum /usr/local/bin/{}
sudo ln -s /usr/bin/uu-hashsum /usr/local/bin/md5sum; sudo ln -s /usr/bin/uu-hashsum /usr/local/bin/b2sum

After, you can give things a look and see if all expected links exist in a functional state:

find /usr/local/bin -type l | wc -l

The output for this, barring any other symbolic links made in this directory for other reasons, should be 107 with the provided instructions.

:dagger: OH MY DAYS WHAT ARE YOU DOING?!

Please don’t perform the step below, until you are damn certain after multiple pre-flight checks you have the symbolic links established as-instructed. Reminder: You don’t have to do this, it’s only if you dislike the bloat of having both Coreutils suites or if you want to see whether this can stand on its own.

Also of note; /usr/bin takes priority over /usr/local/bin so the removal of Coreutils will enforce use of Uutils since links for those exist in /usr/local/bin.

If you wish to remove Coreutils after instantiation, you’ll have to skip dep check for this to work:

sudo pacman -Rdd coreutils

Removal

After having your fun with Uutils, if you find the software just isn’t up to snuff, removal should be pretty painless to perform by modifying the instantiation steps and doing things in reverse:

sudo pacman -S coreutils
find /usr/bin -name 'uu-*' -type l -printf '%f\n' | cut -c -4 | xargs -I{} sudo unlink /usr/local/bin/{}
find /usr/bin -name 'sha*sum' -printf '%f\n' | sort -g | head -n 5 | xargs -I{} sudo unlink /usr/local/bin/{}
sudo unlink /usr/local/bin/md5sum; sudo unlink /usr/local/bin/b2sum
sudo pacman -R uutils-coreutils

Issues

As mentioned in the warning above, this has some problems:

  • Incorrect flags / flag implementation for select commands
  • Missing functions:
    • runcon
    • chcon
    • stty

Those are all of the issues I am aware of thus far, and if you use those binaries then you might be plum out of luck until this is resolved. If you have some other problems people should mind, or if this advice becomes outdated / is incomplete, feel free to let us know! Also, advice on building uutils-coreutils-git from the AUR would be nice to have. I run a system with doas replacing sudo on my primary computational device, so I might be encountering some trouble related to that.

Corrections

  • I misplaced the hyphen for cut in the first series of instructions using find and xargs, so it was making links for uu-<letter > rather than the like-named substitute for GNU Coreutils’ binaries in /usr/local/bin. This would have lead to an unusable system if one who did not know already, hadn’t double-checked their work should they had removed Coreutils.
  • I modified the provided testing methodology for ensuring all instructions rendered the intended result. I shouldn’t had made this thread when I was so very tired.
1 Like

One really should be aware of the circumstance that uutils-coreutils is an ongoing effort which isn’t completed yet.

Thus, for the actual state of progress, there is this overview of the test against the GNU coreutils test suite. Which lists all of the results and current errors / fails.

This graphic summarizes the actual progress:

I’m not aware of their roadmap, but it seems like it may take them more than just a few months to implement the rest of the features to replace GNUs Coreutils.

To me it’s clear that I won’t tinker around with it at the current stage.

1 Like

Yes, I am aware this is an ongoing project. And, this advice might become outdated over time as… when Ubuntu implements it and it becomes a standard carried over into Debian land, it will only be a matter of time before Arch Linux replaces this, likely with a Uutils-only script which will do everything necessary to replace GNU Coreutils with like-named binaries from a future coreutils release, if the pre-flight for that sees GNU Coreutils already exists.

Alternatively, there may be official wiki advice about replacing Coreutils with Uutils, but absent this and for people to test this stuff well into the future, what I’ve written is probably the best DIY alternative to the oxidizr project exclusive to Ubuntu; which does some fairly unsafe things. (You also have to modify it for use in Debian, Pop!_OS and Linux Mint / LMDE since compatibility by default is only for Ubuntu latest.)

I wish Canonical the best of luck, and we’ll see what they end up doing in 2026.

last conference about this

I didn’t wanted to criticize your effort and curiosity, because that’s not the case.

In the long term, a rust implementation will have its benefits and I’m totally for such changes and it’s not relevant to me if Canonical is the first adopter or someone else. As far as I understood, for certain use cases there are significant performance increases. But for the majority of stuff, its mostly negligible and it will be mostly the benefits of rust itself as a language in terms of type and memory safety. Which is already enough of an argument in my eyes to consider a migration of the code base.

Long story short, personally I don’t see the need to tinker around with it. And just based on your short introduction and description… I was just wondering. As the results of the test against GNU coreutils test suit are well documented for each release, there should be a way to use your “inline scripting trickery” to only enable the instantiation of those modules which are already successfully tested ? But this is just a naive assumption from my side.

About the "[I]nline scripting trickery’, I only called it that because it’s literally writing a whole routine to do a bunch of stuff using tools for producing scriptable actions without the need for a file using standard output. My approach is not the most efficient way of doing things, but it’s certainly more accessible than while / for loops.

I don’t know much of whatever else you had mentioned, I assume the testing for this stuff is using the scripts in a working build directory to test against already-installed GNU Coreutils. but if the software in-question doesn’t exist in /usr/bin already, then when invoked by-name alone it will fetch binaries in /usr/local/bin instead.

That is the only reason why this works. I should edit my OP to disclose the stuff in /usr/bin takes precedence over /usr/local/bin because I discovered that just now as I was writing thiss; I thought if the software existed in the same directory, that /usr/local/bin would be prioritised but I was dead-wrong about that. So to test the idea with something safe… -ish to get rid of, try this:

sudo mv /usr/bin/touch /usr/bin/touche
sudo ln -s /usr/bin/touche /usr/local/bin/touch
which touch

touch will be found in /usr/local/bin instead. Now, if you just symlinked touch to /usr/local/bin without renaming it, then which touch would yield /usr/bin/touch.

Question: What about https://aur.archlinux.org/packages/coreutils-uutils ( not https://archlinux.org/packages/extra/x86_64/uutils-coreutils/ )

What reddit told me it is complete drop in replacement. But maybe reddit was wrong.