Cross-platform Rust rewrite of the GNU coreutils https://uutils.github.io/
Find a file
mattsu 43dd238fea
od: make GNU test od.pl pass (#9334)
* feat: Add support for long double floating-point numbers and refine general float formatting.

* feat: Enhance `od` error reporting for file I/O, width, and offset parsing, including overflow detection and input validation.

* feat: Improve long double parsing by converting f128 to f64, enhance overflow error reporting with `libc::ERANGE`, and prevent final offset printing on input errors.

* style: Apply minor formatting adjustments across the `od` module.

* refactor: simplify float formatting logic and update string handling syntax

* fix: Correct float formatting logic to use decimal for numbers within range and exponential otherwise.

* refactor(test): use helper function in test_calculate_alignment

Replace repetitive assert_eq! calls with a new assert_alignment helper
to improve test readability and reduce code duplication. The helper
encapsulates alignment checks for OutputInfo::calculate_alignment,
making tests clearer and easier to maintain.

* feat(cspell): add ERANGE to jargon wordlist

Added "ERANGE" to the dictionary to prevent spell checker flagging it as a misspelling, as it's a valid errno constant from C libraries.

* feat(od): improve width error handling and subnormal float output

Refactor width option parsing in OdOptions to use i18n-compatible error messages via translate! macro, consolidating redundant error branches for better maintainability. Enhance float formatting for f16 and bf16 by introducing format_binary16_like helper to properly display subnormal values with exponential notation, removing the obsolete format_float_simple function and adding subnormal detection functions for accurate representation in od's output.

* refactor(od): simplify format_item_bf16 by removing redundant variable

Remove unnecessary `value` variable in `format_item_bf16` function, eliminating
a redundant cast and inline `f` directly for clarity and minor efficiency gain.

* fix(od): standardize option names in error messages

Remove hardcoded "--" prefixes from localization strings in en-US.ftl and fr-FR.ftl, replacing with a computed display name that includes "--" and optionally the short form (e.g., "--option" or "--option, -s"). Update parse_bytes_option and read_bytes functions to pass an option_display_name, enabling consistent error message formatting across localizations. Add validation to reject zero width values as invalid arguments. Improves user experience by providing clearer, more consistent option references in error outputs.

* refactor: condense format! macro in format_item_bf16 for readability

Removed unnecessary line breaks in the format! expression, keeping the code more concise while maintaining functionality. This improves code style in the float printing module.

* fix(od): add external quoting for filenames in error messages

The MultifileReader now uses `fname.maybe_quote().external(true)` when displaying permission and I/O errors, ensuring filenames are properly quoted for user-facing output (e.g., handling special characters that might confuse shells). This prevents potential issues with filename display in error logs.

* refactor(od): Rename f128_to_f64 to u128_to_f64 for clarity

Renamed the function in input_decoder.rs from f128_to_f64 to u128_to_f64
to accurately reflect its purpose of converting u128 integer bits to f64,
improving code readability and reducing potential confusion over float types.

* refactor(od): simplify error handling in OdOptions using combinators

Use map_err and the try operator to replace a verbose match statement,
making the code more concise and idiomatic Rust. This improves readability
without altering functionality.

* Update src/uu/od/src/od.rs

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

* Update src/uu/od/src/od.rs

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

* Update src/uu/od/src/parse_inputs.rs

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

* Update src/uu/od/src/od.rs

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

* Update src/uu/od/src/parse_inputs.rs

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

* Update src/uu/od/src/parse_inputs.rs

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

* refactor(od): remove leaking from translated error messages in parse_offset_operand

Eliminated use of `.leak()` and unnecessary `.to_string()` calls on translated error strings in the `parse_offset_operand` function. This simplifies error handling, improves memory safety by avoiding intentional leaks, and makes the code cleaner without functional changes.

---------

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
2025-11-28 08:23:55 +01:00
.cargo GNUmakefile: Add a value for cross-build (#9015) 2025-10-26 14:25:58 +01:00
.config create a script for automating code coverage 2025-04-07 10:19:00 +02:00
.devcontainer Update Dockerfile: Don't apt-get jq (preinstalled) 2025-11-25 15:51:29 +09:00
.github CICD.yml: Removed unused code for i586 2025-11-27 21:01:04 +09:00
.vscode od: make GNU test od.pl pass (#9334) 2025-11-28 08:23:55 +01:00
docs installation.md: Ref MSYS2 package 2025-11-23 17:54:23 +09:00
fuzz feat(uucore): add shared hardware detection module 2025-11-24 12:53:58 +01:00
src od: make GNU test od.pl pass (#9334) 2025-11-28 08:23:55 +01:00
tests od: make GNU test od.pl pass (#9334) 2025-11-28 08:23:55 +01:00
util build-gnu.sh: Remove hfs dep from hardlink-case.sh (#9482) 2025-11-27 20:38:07 +01:00
.busybox-config od: several small changes after review 2016-11-09 20:26:55 +01:00
.clippy.toml clippy: set MSRV to 1.85 2025-05-19 09:22:38 +02:00
.codecov.yml maint/CICD ~ configure CodeCov to report but "allow-failure" 2020-05-02 23:26:37 -05:00
.codespell.rc maint/dev ~ add codespell configuration 2021-05-31 07:58:13 -05:00
.editorconfig dotfiles: Add works to cspell dictionary 2025-03-26 16:49:21 +01:00
.envrc dotfiles: Add works to cspell dictionary 2025-03-26 16:49:21 +01:00
.gitignore create a script for automating code coverage 2025-04-07 10:19:00 +02:00
.markdownlint.yaml Run the markdown linter in the CI 2023-03-04 18:44:17 +01:00
.pre-commit-config.yaml Add devcontainer setup and small related fixes 2025-08-18 07:34:16 +00:00
.rustfmt.toml maint/dev ~ add *empty* rustfmt configuration prompt devs to use cargo fmt 2022-02-12 15:26:59 -06:00
build.rs Merge pull request #9153 from oech3/nognuhashsumbin 2025-11-08 23:55:49 +01:00
Cargo.lock od: make GNU test od.pl pass (#9334) 2025-11-28 08:23:55 +01:00
Cargo.toml replace number_prefix by unit-prefix 2025-11-18 09:59:46 +01:00
CODE_OF_CONDUCT.md parent 9d5dc500e6 2023-03-04 18:43:40 +01:00
CONTRIBUTING.md doc: fix warnings from markdown linter 2025-05-18 21:08:27 +02:00
Cross.toml Cross.toml: Install tzdata in container 2025-05-29 14:00:25 +02:00
deny.toml Bump linux-raw-sys from 0.11 to 0.12 (#9019) 2025-10-25 20:21:26 +02:00
DEVELOPMENT.md build-gnu.sh: Use any profile & cleanup arg 2025-11-18 16:49:41 +09:00
flake.lock flake: drop flake-utils, refactor 2025-03-05 21:52:02 +01:00
flake.nix flake.nix: Add cspell 2025-05-25 17:57:18 +02:00
GNUmakefile GNUmakefile: Use .* for libstdbuf* matching 2025-11-20 15:00:42 +09:00
LICENSE update of the license file to make it generic (#5545) 2023-11-16 10:40:31 +01:00
Makefile refactor ~ (makefiles) fix spelling + add spell-checker exceptions 2021-05-31 08:23:58 -05:00
Makefile.toml Reformat TOML files with taplo 2023-06-08 09:07:19 +02:00
oranda.json website: fix changelog config 2023-08-28 10:36:01 +02:00
README.md README.md: note that separator is needed for PROG_PREFIX 2025-11-22 14:49:13 +09:00
README.package.md coreutils: Add a default readme for the packages 2024-06-30 10:52:10 +02:00
renovate.json chore(config): migrate config renovate.json 2024-10-31 15:26:47 +00:00
SECURITY.md Document the security process (#8633) 2025-09-14 13:56:20 +02:00

uutils logo

uutils coreutils

Crates.io Discord License dependency status

CodeCov MSRV Weblate


uutils coreutils is a cross-platform reimplementation of the GNU coreutils in Rust. While all programs have been implemented, some options might be missing or different behavior might be experienced.

To install it:

cargo install coreutils
~/.cargo/bin/coreutils

Goals

uutils coreutils aims to be a drop-in replacement for the GNU utils. Differences with GNU are treated as bugs.

Our key objectives include:

  • Matching GNU's output (stdout and error code) exactly
  • Better error messages
  • Providing comprehensive internationalization support (UTF-8)
  • Improved performances
  • Extensions when relevant (example: --progress)

uutils aims to work on as many platforms as possible, to be able to use the same utils on Linux, macOS, Windows and other platforms. This ensures, for example, that scripts can be easily transferred between platforms.

Documentation

uutils has both user and developer documentation available:

Both can also be generated locally, the instructions for that can be found in the coreutils docs repository.

Use weblate/rust-coreutils to translate the Rust coreutils into your language.

Requirements

  • Rust (cargo, rustc)
  • GNU Make (optional)

Rust Version

uutils follows Rust's release channels and is tested against stable, beta and nightly. The current Minimum Supported Rust Version (MSRV) is 1.85.0.

Building

There are currently two methods to build the uutils binaries: either Cargo or GNU Make.

Building the full package, including all documentation, requires both Cargo and GNU Make on a Unix platform.

For either method, we first need to fetch the repository:

git clone https://github.com/uutils/coreutils
cd coreutils

Cargo

Building uutils using Cargo is easy because the process is the same as for every other Rust program:

cargo build --release

Replace --release with --profile=release-fast or --profile=release-small to use all optimizations or save binary size.

This command builds the most portable common core set of uutils into a multicall (BusyBox-type) binary, named 'coreutils', on most Rust-supported platforms.

Additional platform-specific uutils are often available. Building these expanded sets of uutils for a platform (on that platform) is as simple as specifying it as a feature:

cargo build --release --features macos
# or ...
cargo build --release --features windows
# or ...
cargo build --release --features unix

To build SELinux-specific features, including chcon and runcon, ensure that libselinux and libclang are installed on your system. Then, run the following command:

cargo build --release --features unix,feat_selinux

If you don't want to build every utility available on your platform into the final binary, you can also specify which ones you want to build manually. For example:

cargo build --features "base32 cat echo rm" --no-default-features

If you want to build the utilities as individual binaries, that is also possible:

cargo build --release --bins --workspace --exclude coreutils --exclude uu_runcon --exclude uu_chcon

Each utility is contained in its own package within the main repository, named "uu_UTILNAME". To build selected individual utilities, use the --package [aka -p] option. For example:

cargo build -p uu_base32 -p uu_cat -p uu_echo -p uu_rm

GNU Make

Building using make is a simple process as well.

To simply build all available utilities (with debug profile):

make

In release-fast mode:

make PROFILE=release-fast

To build all but a few of the available utilities:

make SKIP_UTILS='UTILITY_1 UTILITY_2'

To build only a few of the available utilities:

make UTILS='UTILITY_1 UTILITY_2'

Installation

Install with Cargo

Likewise, installing can simply be done using:

cargo install --path . --locked

This command will install uutils into Cargo's bin folder (e.g. $HOME/.cargo/bin).

This does not install files necessary for shell completion or manpages. For manpages or shell completion to work, use GNU Make or see Manually install shell completions/Manually install manpages.

Install with GNU Make

To install all available utilities:

make install

To install all utilities with all possible optimizations:

make PROFILE=release-fast install

To install using sudo switch -E must be used:

sudo -E make install

To install all but a few of the available utilities:

make SKIP_UTILS='UTILITY_1 UTILITY_2' install

To install only a few of the available utilities:

make UTILS='UTILITY_1 UTILITY_2' install

To install every program with a prefix (e.g. uu-echo uu-cat):

make PROG_PREFIX=uu- install

PROG_PREFIX requires separator -, _, or =.

To install the multicall binary:

make MULTICALL=y install

Set install parent directory (default value is /usr/local):

# DESTDIR is also supported
make PREFIX=/my/path install

Installing with make installs shell completions for all installed utilities for bash, fish and zsh. Completions for elvish and powershell can also be generated; See Manually install shell completions.

To skip installation of completions and manpages:

make COMPLETIONS=n MANPAGES=n install

Manually install shell completions

The uudoc binary generates completions for the bash, elvish, fish, powershell and zsh shells to stdout.

Install uudoc by

cargo install --bin uudoc --features uudoc --path .

Then use the installed binary:

uudoc completion <utility> <shell>

So, to install completions for ls on bash to /usr/local/share/bash-completion/completions/ls, run:

uudoc completion ls bash > /usr/local/share/bash-completion/completions/ls.bash

Completion for prefixed cp with uu- on zsh is generated by

env PROG_PREFIX=uu- uudoc completion cp zsh

Manually install manpages

To generate manpages, the syntax is:

uudoc manpage <utility>

So, to install the manpage for ls to /usr/local/share/man/man1/ls.1 run:

uudoc manpage ls > /usr/local/share/man/man1/ls.1

Un-installation

Un-installation differs depending on how you have installed uutils. If you used Cargo to install, use Cargo to uninstall. If you used GNU Make to install, use Make to uninstall.

Uninstall with Cargo

To uninstall uutils:

cargo uninstall coreutils

Uninstall with GNU Make

To uninstall all utilities:

make uninstall

To uninstall every program with a set prefix:

make PROG_PREFIX=uu- uninstall

To uninstall the multicall binary:

make MULTICALL=y uninstall

To uninstall from a custom parent directory:

# DESTDIR is also supported
make PREFIX=/my/path uninstall

GNU test suite compatibility

Below is the evolution of how many GNU tests uutils passes. A more detailed breakdown of the GNU test results of the main branch can be found in the user manual.

See https://github.com/orgs/uutils/projects/1 for the main meta bugs (many are missing).

Evolution over time

Contributing

To contribute to uutils, please see CONTRIBUTING.

License

uutils is licensed under the MIT License - see the LICENSE file for details

GNU Coreutils is licensed under the GPL 3.0 or later.