返回资讯中心
外部精选
软件工程
#开发者实时流

Ubuntu 26.04 的 Rust coreutils 与 GNU 差距有多大?开发者对比 27 个工具

来源标题:How close are Ubuntu 26.04's Rust coreutils to GNU? I diffed 27 utilities

一项针对 Ubuntu 26.04 LTS 中替换 GNU coreutils 的 Rust 版 uutils 的对比测试显示,27 个工具在约 2000 个生成用例下与 GNU coreutils 9.12 的行为一致性存在差异。测试覆盖 Ubuntu 26.04 自带的 uutils 0.10.0、最新版 0.12.0 及 main 分支,以退出状态、stdout、stderr 和文件改动为评分标准。部分差异已在上游修复,但未进入 Ubuntu 26.04。

Hacker News 最新karol-kulesza2026/11/7 · 今天12 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

用 port-anything 制作,该工具用于检查重写版本是否仍与被替换程序行为一致:npx port-anything compare <reference> <candidate>。

Ubuntu 26.04 LTS 用 uutils(Rust 重写版)替换了 GNU coreutils。我想知道两者到底有多接近,于是对 27 个工具分别用每个工具约 2,000 个生成用例在两者上运行,并以当前 GNU(9.12)为基准评分。

Ubuntu 26.04 LTS 将 uutils(Rust 重写版)作为 coreutils 发布,同时把 GNU coreutils 9.7 以 gnu* 的名字保留在旁边。四月的版本是 uutils 0.8.0;九月的一次更新(0.10.0-1ubuntu2~26.04.1,位于 26.04.1 中)将其升级到 0.10.0,本次测试的就是这个版本。0.8.0 未测试。本次比较的是这两者,外加 uutils 0.12.0(最新发布版)和 uutils main,基准为当前 GNU 发布版 GNU coreutils 9.12,覆盖 27 个工具。

一致性 = 对某个工具的所有 flag 取平均,即在生成的用例中,候选版本与 GNU 9.12 匹配(退出状态、stdout、stderr、被修改的文件)的比例。每个单元格是三次运行的平均值,三次运行的语料分别用不同的种子(42、7、1234)生成;若各次运行相差超过 5 个百分点,则显示范围。n/a:每个 flag 的用例太少,无法评分。

已在上游修复,但尚未进入 Ubuntu 26.04。以下是 Ubuntu 用户今天最可能遇到的问题:

printf 'apple\nBanana\ncherry\n' > a; printf 'Apple\nbanana\ncherry\n' > b comm -12 a b

Ubuntu 的 uutils 0.10.0 会输出 comm: file 1 is not in sorted order 并以 1 退出;GNU 和 uutils 0.12.0+ 会输出 cherry 并以 0 退出。由 #14047 修复(2026-08-29 合并)。

在主目录下直接运行 ls:0.10.0 会把 Desktop Documents Videos 排在 snap test.sh 之前(按字节序);GNU 和 uutils 0.12.0+ 按 locale 排序。已在 #12474 中报告,由 #11841 修复。

nl -v -1(从 -1 开始编号)被我测试的每个 uutils 构建拒绝;已于 2026-11-02 在 main 上修复(#15999,PR #16018),时间在这些运行之后。

GNU 自身的漂移。GNU 9.12 会给标准输入的 head -v 头部加引号;9.7 不会:

printf 'a\n' | head -v

GNU 9.12 和 uutils main 输出 ==> 'standard input' <==,而 GNU 9.7 和 uutils 0.10.0/0.12.0 输出 ==> standard input <==。同样,cut -F 在 GNU 9.11+ 和 uutils 0.12.0+ 中存在,但 Ubuntu 的 GNU 9.7 中没有。

上游仍未解决,已由他人报告:

examples.sh 在全部五个构建上重放单行示例: docker run --rm ubuntu-uutils bash /ub/examples.sh

设置 Ubuntu 26.04.1 LTS 容器,x86_64,bubblewrap 沙箱,每个用例 5 秒超时。 GNU coreutils 9.12 从 GNU tarball 构建(sha256 a480198559733e9b3da999e90543ac6f888a2caa544d8d664c5a1f17e528e210);GNU 9.7 = Ubuntu 的 gnu-coreutils;uutils 0.10.0 = Ubuntu 的 /usr/bin/coreutils(rust-coreutils 0.10.0-1ubuntu2~26.04.1);uutils 0.12.0 发布版二进制;uutils main 位于 90b48bf(报告版本 0.13.0)。 port-anything 0.1.3。每个工具的语料:从 GNU 9.12 的 --help 生成 1,000 个用例(种子 42、7 或 1234,存储在 corpus/ 中),再加上约 1,000 个由 run 通过变异从这些用例派生的用例。 cp、mv 和 ln 被排除(Ubuntu 将 cp 和 mv 保留在 GNU 上;ln 需要本次运行未做的文件设置)。

这与 uutils 自己的数字有何不同:uutils 运行 GNU 9.12 的测试套件(截至 2026-10-30,720 个测试中 664 个通过,coreutils-tracking)。那些是 GNU 手写的覆盖所有工具的测试;本次是 27 个工具中每个 flag 的生成用例。

复现 docker build -t ubuntu-uutils . for s in 42 7 1234; do docker run --rm --init --security-opt seccomp=unconfined --security-opt apparmor=unconfined
--security-opt systempaths=unconfined -v "$PWD/out:/out" -e OUT=/out/seed$s -e SEED=$s ubuntu-uutils /ub/run.sh done

在一台 2019 年的 Intel 笔记本上,每个种子约需 1 小时 40 分钟。每个工具的 out/seed<S>/<util>/run.txt 包含每个候选版本的一致性;在项目内运行 port-anything run --cluster <n> 可显示差异所在。重跑的结果与表格相差约一个百分点以内:运行会排除那些在重跑之间参考输出发生变化的用例,还有少数用例在负载下超时。 沙箱需要三个 --security-opt 标志(bubblewrap 在容器内创建命名空间)。 Dockerfile、run.sh、examples.sh:上述镜像和脚本。 corpus/seed<S>/<util>.jsonl.gz:每个种子的生成用例(argv、stdin、输入文件)。 results/parity.csv:每个单元格,按种子和平均值。results/cases-and-command-lines.csv:每个工具和种子的用例数与不同命令行数。results/versions.txt:工具和二进制版本。 results/heatmap.svg|png:完整图表;results/heatmap-social.svg|png:11 行,1200×675。

制作方式 我构建了 port-anything,用于检查重写版本是否仍与被替换程序行为一致。它读取参考版本的 --help,按 flag 生成用例,在沙箱中运行每一方,并对差异评分。在 Ubuntu 26.04 上,GNU sort 以 gnusort 安装(约一分钟;在那里得分为 91.5%): npx port-anything compare gnusort 'coreutils sort' --budget 1000

感谢 uutils 维护者:0.10.0 列中的若干差距在我查看时已经修复。

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →