1
0
Fork 0
mirror of https://git.anardil.net/austin/coreutils.git synced 2026-10-24 15:52:04 +00:00
Unix core utilities implemented in Haskell
  • Haskell 93.2%
  • Shell 6.7%
  • Makefile 0.1%
Find a file
Gandalf- 3ec2f4f431 head -n keeps line endings as they were, as BSD does
Lines are split with lineSplit, which keeps each terminator, so an
unterminated last line stays unterminated and CRLF keeps its CR; Q.lines
dropped both. One group of n lines rather than n groups of one, which
is also faster than the old path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 13:37:07 -07:00
Coreutils head -n keeps line endings as they were, as BSD does 2026-10-22 13:37:07 -07:00
src readlink complete 2024-11-07 17:52:17 -08:00
test head -n keeps line endings as they were, as BSD does 2026-10-22 13:37:07 -07:00
.gitignore switch to package.yaml 2025-12-30 13:29:53 -08:00
.hspec more parallel tests 2026-03-29 10:19:49 -07:00
CLAUDE.md nl and fold report an empty numeric operand instead of crashing 2026-10-20 21:01:59 -04:00
LICENSE Initial commit 2018-09-02 09:39:12 -07:00
Makefile nl, uniq state refactoring 2026-03-29 11:46:05 -07:00
package.yaml homepage is code.anardil.net, public.anardil.net is retired (#289) 2026-10-21 00:02:20 -04:00
README.md wc, more tests 2026-05-25 14:46:51 -07:00
stack.yaml stack lts 24.24 2025-12-30 12:52:08 -08:00
todo.md addrinfo minor improvements 2023-08-22 22:33:42 -07:00

coreutils

Unix core utilities implemented in Haskell.

Goals are:

  • Idiomatic implementations
  • Fast, lazy IO
  • Feature parity with BSD utils
  • Fully tested
  • Platform independent
Utility Idiomatic Fast Lazy Tests Complete
addrinfo ✓ - - ✓ 80
awk ✓ ✓ ✓ 40
basename ✓ - - ✓ ✓
cat ✓ ✓ ✓ ✓
cmp ✓ ✓ 50
cut 75 ✓ 90 90
dirname ✓ - - ✓ ✓
echo ✓ - - ✓ ✓
env ✓ - - ✓ ✓
exit ✓ - - ✓ ✓
false ✓ - - ✓ ✓
head ✓ ✓ ✓ ✓ ✓
ls ✓ ✓ - ✓ 50
mkdir ✓ - - ✓ ✓
nl ✓ ✓ ✓ ✓ ✓
nologin ✓ - - - ✓
paste ✓ ✓✓ ✓ ✓ ✓
pwd ✓ - - - ✓
random ✓ - - ✓ ✓
readlink ✓ - - ✓ ✓
realpath ✓ - - ✓ ✓
rev ✓ ✓ ✓ ✓ ✓
seq ✓ 75 ✓ ✓ ✓
sleep ✓ - - ✓ ✓
split ✓ ✓ ✓ ✓ ✓
sponge ✓ ✓ - ✓ ✓
strings ✓ ✓ ✓ ✓ ✓
sum ✓ ✓ ✓ ✓ ✓
tac ✓ ✓ ✓ ✓ ✓
tee ✓ ✓ ✓ ✓ ✓
test ✓ ✓ ✓ ✓ ✓
tr ✓ 75 ✓ ✓ ✓
truncate ✓ ✓ - ✓ ✓
true ✓ - - ✓ ✓
uniq ✓ ✓ ✓ ✓ ✓
wc ✓ ✓ ✓ ✓
which ✓ - - - ✓
whoami ✓ - - - ✓
yes ✓ ✓ ✓ - ✓
Symbol Meaning
✓✓ Superior
✓ Complete
% % Partial
- Not applicable

Usage

This project compiles to a single executable which detects which utility to call depending on the name of the binary.

make release

or

stack install --flag coreutils:release

Platform Independent

With utils on your path, you can call any utility by name, using the name as the first argument.

I leaf@elm ~> utils echo hello | utils rev
olleh
C:\Users\leaf>utils echo hello | utils rev
olleh

This is the best option for trying things out without committing your entire shell to these implementations. The testing done is mostly thorough, but there's some crazy usage of the coreutils out in the wild; like cat - - - in build scripts. Who needs to read stdin three separate times? The standard Haskell IO libraries make some sane assumptions that things like this don't happen, so this project has balance ugly workarounds with idomatic behavior. Where reasonable, idomatic is preferred. Further, this project relies on the Haskell IO libraries for platform independence - where they decided to simplify (permissions, file types), this project does also.

Linux, FreeBSD, MacOS

If you do want to commit, symlink the utilities you'd like to expose to your $PATH variable. If ~/.local/bin/ has precedence over /bin/ and /usr/bin/, these are the versions your shell will use.

cd ~/.local/bin/
ln -s utils cat
ln -s utils sleep
ln -s utils rev
...
I leaf@elm ~> which which
/home/leaf/.local/bin/which

On Windows

Symlinking doesn't appear to change the name reported by System.Environment.getProgName, so you'll need to create copies of the binary with different names.

PS C:\> cd (Split-Path -Parent (Get-Command utils.exe).Path)
PS C:\Users\leaf\AppData\Roaming\local\bin> cp utils.exe which.exe
PS C:\Users\leaf\AppData\Roaming\local\bin> cd C:\
PS C:\> which calc.exe
C:\WINDOWS\system32\calc.exe
PS C:\> which which.exe
C:\Users\leaf\AppData\Roaming\local\bin\which.exe