ls but 'The Unix Way'
What is The Unix Philosophy?
The Unix philosophy, originated by Ken Thompson, is a set of cultural norms and philosophical approaches to minimalist, modular software development...
But in particular, Doug McIlroy, and later, Peter H. Salus, honed in on the following:
- Write programs that do one thing and do it well.
- Write programs to work together.
- Write programs to handle text streams, because that is a universal interface.
Unix provides for this methodology in several ways:
- Pipelines allow for output of one progroam to feed into another;
- Everything (except some things) is a file;
- Scripting and chaining of commands is supported;
https://en.wikipedia.org/wiki/Unix_philosophy
Does 'ls' qualify?
ls is a particularly useful utility, but it falls short of the Unix path in many ways. Most eggregiously, it does two things: scan the filesystem collecting data, and display such data.
As a result, it has two distinct sets of flags that control it -- ones to deal with the filesystem, and ones that sort and otherwise format the display.
Over decades, many flags were added to allow ls to do an adequate job on both ends, but we lost in the process.
83 distinct flags or options are offered by GNU ls. I have a T-shirt with the summary of ls options, and it is a lot of text! Such complexity is directly resultant from the lack of domain separation between the distinct tasks the utility performs.
What's worse, is that ls is not really composable. There is nothing you could pipe in as a substitute for it directly hitting the filesystem. The output is human-readable, and cannot be externally manipulated easily with text tools.
How should it work?
Clearly, the functionality we regard as 'ls' should be performed by at least two programs: the file-system scanner and the formatter. The first should work much like ls today, but generate a standard textual output which can be further processed and displayed by standard unix utilities like awk...
The simplest way is to provide CSV data -- comma-separated fields containing name, size, type, permissions, etc. You could do JSON or XML, but it is an overkill and will add unnecessary overhead, as the fields are well-known and always identical in this case.
An experiment
I wrote a very primitive version to see what it's like. It just dumps the contents of a directory, like this:
./a.out
name, size, type, perms, owner, group, modified
a.out,14472,10,775,1000,1000,1767924426
..,4096,4,775,1000,1000,1767919427
.,4096,4,775,1000,1000,1767924426
zls.c,3745,10,664,1000,1000,1767924420
Note that output is textual but not fully decoded -- things like how to display dates and users is up to the presentation program. But I did provide an -h (for 'human') option to make life easier in most common cases:
./a.out -h
name, size, type, perms, owner, group, modified
a.out,14472,file,rwxrwxr-x,stack,stack,2026-01-08 18:07:06
..,4096,dir,rwxrwxr-x,stack,stack,2026-01-08 16:43:47
.,4096,dir,rwxrwxr-x,stack,stack,2026-01-08 18:07:06
zls.c,3745,file,rw-rw-r--,stack,stack,2026-01-08 18:07:00
This is easier, but in some cases I can see the need for processing dates or whatnot, easier without the -h.
To make it more useful it should be piped into something that provides nicer output. Here it gets a little hairy:
./a.out -h | tail -n +2 | sort -t',' -k1 | tail -n +3 | awk -F',' '{print $4, $5i, $3, $7, $1, $2}'
rwxrwxr-x stack file 2026-01-08 18:07:06 a.out 14472
rw-rw-r-- stack file 2026-01-08 18:07:00 zls.c 3745
OK, this looks kind of like 'ls -l', but the pipeline is a little painful-looking. We need to:
- strip the column name line
- sort by comma-separated field 1
- strip . and ..
- print fields in desired order
Also note that because of my shortcut of fixing the date format in the filesystem scanner we are now stuck with the wrong-looking date/time format. And that is why it should really be done at the output level!
Some Difficult Things
As is, I noticed some difficulties:
- Alignment is hard! Tabs don't match up, and I need to see if there is anything that makes column-aligned
- Parametrizing a script with getopts is a pain!
- My linux-fu and awareness of proper linux utilities to do things is insufficient.
I should probably look at a few CSV-related utilities which will hopefull simplify dealing with the output of something like this.
Is it worth it?
Well, that was a lot of work to create a tiny subset of what ls does. But it feels a little more correct.
But having a filesystem scanner separate from the display allows for reuse -- things like find can be built around that.
Discuss on BBS
index
© 2021-2025 StackSmith All Rights Reserved
This gemlog is served without any disk reads!
🏭 Fornax inside...