posixutils-rs
Just one section in the weekend Bonus Drop, as I spent far too much time trying to fix the issues preventing the thing you’re about to read about from building on macOS. That also means no TL;DR!
posixutils-rs

- NB 1: Perplexity, using Claude 2 Sonnet, was used to add the descriptions to the list of utilities.
- NB 2: The Open Group has the HTML version of POSIX.1-2024 up! “Shells and Utilities has the full listing of POSIX utilities that you can explore.”
- NB 3: The project did not build under macOS 15 beta 3. All testing was done on Ubuntu 22.04.
POSIX (Portable Operating System Interface) is a family of standards specified by the IEEE Computer Society for maintaining compatibility between operating systems. It defines the application programming interfaces (APIs), command line shells, and utility interfaces that should be available on POSIX-compliant operating systems. We’ve talked about POSIX somewhat frequently in the Drop, and recently covered the new 2024 version of the standard.
We’ve also talked about a project that aims to port the GNU coreutils over to Rust, but there’s also a project — posixutils-rs — underway with a similar aim to port the suite of core POSIX-compliant command line utilities to Rust. It has three core goals:
- create clean, safe, race-free utilities that maximize compatibility with existing shell scripts while minimizing bloat
- implement utilities using idiomatic Rust code and leveraging existing Rust community crates where possible
- conform to the POSIX standard (specifically SuSv3) as the baseline, only adding popular non-POSIX options needed for compatibility
One reason to undertake this effort is that the suite of POXIX utilities is larger than GNU’s coreutils (and/also: GNU coreutils are kinda bloated). By porting them to Rust, there’s more of a safety guarantee (you can 100% write unsafe Rust programs). And, since the POSIX utilities themselves are more minimal than GNU coreutils, that, combined with the project’s promise to minimize dependencies,
Another difference is the size of the binaries (built with --release):
find -maxdepth 1 -type f -executable \
| xargs stat -c '%s' \
| Rscript -e 'scan("stdin") |> summary()'
Min. 1st Qu. Median Mean 3rd Qu. Max.
407112 942456 956964 1151352 1044834 3805456
The same summary() for their counterparts on my main Ubuntu 22.04 box is:
Min. 1st Qu. Median Mean 3rd Qu. Max.
2346 35240 43420 58588 68104 282088
These Rust versions had better be super safe for that tradeoff. I’ll re-run that comparison when the project finalizes utility coverage.
Speaking of utility coverage, here is that list of the current set of ported utilities that I mentioned at the top of the section:
ar: create, modify, and extract from archivesasa: interpret ASA carriage control charactersbasename: strip directory and suffix from filenamesbc: arbitrary-precision arithmetic languagecal: display a calendarcat: concatenate and print fileschgrp: change group ownershipchmod: change file modes or Access Control Listschown: change file owner and groupcksum: checksum and count the bytes in a filecmp: compare two filescomm: select or reject lines common to two filescompress: compress datacp: copy files and directoriescsplit: split files based on contextcut: cut out selected fields of each line of a filedate: display or set the system date and timedd: convert and copy a filedf: report file system disk space usagediff: compare two filesdirname: strip non-directory suffix from file namedu: estimate file space usageecho: display a line of textenv: set environment and execute commandexpand: convert tabs to spacesexpr: evaluate expressionsfalse: do nothing, unsuccessfullyfile: determine file typefind: search for files in a directory hierarchyfold: wrap each input line to fit in specified widthgetconf: get configuration valuesgrep: search a file for a patternhead: output the first part of filesid: return user identityipcrm: remove IPC resourcesipcs: report IPC statuskill: terminate or signal processeslink: call the link function to create a link to a fileln: make links between fileslogger: enter messages into the system loglogname: return the user’s login namels: list directory contentsmesg: control write access to your terminalmkdir: make directoriesmkfifo: make FIFOs (named pipes)mv: move (rename) filesnice: run a program with modified scheduling prioritynl: number lines of filesnm: list symbols from object filesnohup: run a command immune to hangupsod: dump files in octal and other formatspaste: merge lines of filespathchk: check whether file names are valid or portablepr: convert text files for printingprintf: format and print datapwd: print name of current/working directoryreadlink: display value of a symbolic linkrenice: alter priority of running processesrm: remove files or directoriesrmdir: remove empty directoriessleep: delay for a specified amount of timesort: sort lines of text filessplit: split a file into piecesstrings: print the strings of printable characters in filesstrip: remove unnecessary information from strippable filesstty: change and print terminal line settingstabs: set tabs on a terminaltail: output the last part of filestee: read from standard input and write to standard output and filestest: evaluate expressiontouch: change file timestampstput: change terminal characteristicstr: translate or delete characterstrue: do nothing, successfullytsort: topological sorttty: return user’s terminal nameuname: print system informationuncompress: expand compressed dataunexpand: convert spaces to tabsuniq: report or omit repeated linesunlink: call the unlink function to remove the specified fileuudecode: decode a binary fileuuencode: encode a binary filewc: print newline, word, and byte counts for each filewho: display who is logged inwrite: write to another userxargs: build and execute command lines from standard input
FIN
Remember, you can follow and interact with the full text of The Daily Drop’s free posts on Mastodon via @dailydrop.hrbrmstr.dev@dailydrop.hrbrmstr.dev ☮️
Leave a comment