It might not be KISS, but I think exa embodies the UNIX philosophy. It does one thing (show me the contents of a folder) and it does it well (arguably better than ls as long as the consumer is a human).
The UNIX philosophy isn't "only call one syscall", so getting more info on the files it's displaying is far game in my book.
I have nothing against exa, but the two examples in this post are are not correct for any sort of recent system.
> Here’s an example. exa, by default, runs the stat system call on every file it encounters.
So does "ls" ... for at least last 20 years. Just checked on random Ubuntu system I had -- executables and dirs are highlighted with different colors.
> exa makes heavy use of colours, treating them as opt-out rather than opt-in: it will highlight files and data differently based on their type or meaning.
So does ls -- I see colors in default install. Yes, you need an environment variable to enable this, but all the modern distros set this anyway.
So based on that page, it seems that the only thing that EXA does differently is that it upgrades ls's 16 color palette to 256 colors.
There's a features page on their website that shows some more tricks it can do, like smarter file type colouring, generating a tree view and showing the git status of files.
I'm still not entirely convinced that it's a must-have, but it's more than just ls with fancy colours.
Personally, I'd much rather have seen an output format like JSON as a feature instead, so you can do some easier scripting through exa and jq. I'm sure there are other tools out there to serve thst purpose, though.
Yes, they really need to call out what makes it different. The front page makes it sound mostly like an alias to ls with specific options + an additional call to `git status`.
I've been using `exa` for over a year now, and I use it as an alias for both `ls` and `tree`. I don't really notice any benefit compared to using `ls`, but I really prefer its tree mode over the default `tree` command. It's nice being able to use the same CLI args and have a similar output format for both `tree` and `ls`.
Did the link get edited or something? OP takes me to https://the.exa.website/introduction, which has a nice tutorial with all of the features and how to install.
No? That "introduction" link mentions 2 differences: "The computer is no longer the bottleneck." -> exa runs stat() calls; and "256-colour terminals are everywhere." -> exa uses color by default.
But the thing is, if you install any modern system (ubuntu or fedora or pretty much anything else) and type "ls", it does those two things as well! Your default config will alias ls to enable color by default, and this ls invocation will be doing stat on every page.
So anyone who knows "ls" even a bit would, on looking on that particular page, say, "Huh? That's your special feature? my ls does this already and I don't have to do anything to install it. [close window]"
To reiterate, EXA does have features that "ls" does not. It just that https://the.exa.website/introduction page does not list those features at all. If you want to convince people to switch to EXA, you better point them to a different page.
I've been using lsd[0] as my ls replacement for a while. I like that it has a config file for defaults, so I don't have to change a bunch of aliases when setting up a new system.
Lately I have been creating "three sided cards" which usually have a photograph or art reproduction on the front, a back side with an explanation and qr code that point to a web site.
Each of these is a package of files in a directory.
In the last few days I've been developing "ls-like" functionality for these cards with the specific goal of listing cards that need maintenance. For instance I did a series of photographs where I printed the cards but didn't generate the web sites.
Architecturally it's interesting, particularly in that there is the selection logic, the way you display a card, and then the realization that you ought to be able to do something to a card other than display metadata for it but select the cards with the same facility you use to select them for "ls".
I'm not gonna hate on this too much; side projects like this are fun and help the creator understand the filesystem-side of their operating system. The colors are pretty, there's some nifty features to better understand the file list you're staring at.
This won't ever replace `ls` because it's not POSIX compliant, but that's okay because I don't think it needs to be. I have run into cases where downstream packages have dependencies on non-POSIX commands which gets a little annoying, but you can always choose something else (or take it on yourself to re-implement their idea in a POSIX-compliant way), which is the whole point of open source software.
It's like saying ripgrep won't ever replace grep... It's true but for many use cases (for example in many shell scripts) but there are much more people using ripgrep than just its creator.
exa is already several years old and has 15 K thousands stars on Github. Not to mention all the people using it that never bothered to give it a star.
For me, the killer feature of exa is the git integration. Being able to do 'l' (aliased to 'exa --long --all --links --git') and seeing the git status (added, ignored, modified, etc) along with other file details is awesome.
Author here; I have experience using it 100s of times per day since I wrote it. There are a couple of things that I don't use (like selinux) support that may be a little hinky. I have a few loyal users, but I don't hear much feedback about troubles they might have.
It has kind of a long history. I first did a prototype in Python about year 2000 and then a year later a re-write in C which I used for a couple of decades and then an I think pretty nice 3rd gen in Nim. (Often one doesn't really get it all layered correctly until 3rd try, even for something kinda simple like `ls`.)
Miller columns a la NeXTStep is something easy to simulate with `lc` via the glob abbreviation { paste <(lc -1m25 ../..) <(lc -1m25 ..) <(lc -1m25 .) | column } and in general the program is more like an "ls construction toolkit" than a fixed classifier/turnkey ls. But really the readme covers many more details.
Among unusual ones is "tweak" files; Got a directory that you want special defaults for? Just drop in a `.lc` file. (With some parallel hierarchy features when perms do not allow that directly.) This is sort of like Windows remembering what sorting/layout options you clicked on, but manual and opt-in (and far more general).
Main feature here seems to be colors, but GNU `ls` can also color files based on their file extension and also differentiate between pipes, executables, and working and broken links [1].
It does a lot more than just colours. It has git integrations, a more concise output, built-in tree, grid view, icons (note they're not showing correctly in below output) and much more.
$ ll
drwxrwxr-x - dan 27 Oct 15:12 -I .idea
.rw-rw-r-- 15 dan 9 Sep 11:44 -N .tool-versions
drwxrwxr-x - dan 9 Sep 11:53 -I dist
drwxrwxr-x - dan 23 Sep 18:53 -- docs
.rw-rw-r-- 376 dan 29 Jun 12:26 -I some-project.iml
drwxr-xr-x - dan 10 Sep 12:28 -I node_modules
.rw-rw-r-- 301 dan 21 Oct 13:17 -N override.env
edit: if it wasn't clear, the above output is a subset of the real output.
> icons (note they're not showing correctly in below output)
This is often my biggest annoyance with command line tools that rely on dedicate fonts and private use icons. The functionality is great, but making sure you've got the right fonts installed on every machine/terminal is sometimes tedious enough that I give up on things like exa.
These days I think exa does not show icons by default, which is I think the right decision.
I've been loving all the new rust-based CLI tools; you can find a lot of them here [0].
So far I've used ripgrep, fd-find, sd, exa, bat. I care less about speed and more about ease-of-use and beautiful output. Another bonus is standardized tooling between Mac and Linux; little bsd differences have been driving me nuts since I took a job that forced me into a MacBook, but these tools solve that issue and are easy to install with Homebrew.
> little bsd differences have been driving me nuts since I took a job that forced me into a MacBook, but these tools solve that issue and are easy to install with Homebrew.
I'm in the same boat as you - I love the the rust-based CLI tools. I would also recommend installing the GNU coreutils via homebrew (https://formulae.brew.sh/formula/coreutils). This lets you run the GNU coreutils by prefixing them with a `g`, like `gsed` rather than `sed`.
I use the gnu coreutils because small things like cli flags are different for the macos implementations. So for example some aliases in my .zshrc didn’t work on my MacBook. I come from a Linux background so it was nice for me to have coreutils behave exactly how I’m used to. Some people prefer gnu software for ideological reasons too.
It was one of the flags for ‘ls’ in particular that made me switch. There’s a way to add the gnu coreutils to your path without the g prefix so I never even notice the difference.
Not GP, but I'd imagine one use case would be for writing scripts to be used on other machines where the tools might not be installed, e.g. writing scripts on a mac to be run on Linux servers. If for example you want to script something for CI to be run on a Linux server, I can imagine having the GNU utilities in the default path on a Mac would be useful, since getting the Rust tools installed on the CI server is probably not worth the effort.
> Another bonus is standardized tooling between Mac and Linux;
This is why I just use a modern cross platform shell that has everything built in. My choice is PowerShell since I flip between Linux and Windows, Nushell is also a solid choice if you want something more Unixy.
The standardized tooling is called POSIX, and you already have it installed — it’s easy enough to train the GNUisms out of your fingers and it will reward you in the end.
The standard is also the lowest common denominator. I think it's a useful skill to be able to write POSIX-only shell scripts, but in my day to day use I'd rather have the GNU extensions, knowing that they aren't portable. Plus the GNU versions of the programs generally are still portable anyway.
The best part is that most of them even work well under Windows, too, and that really is a nice breath of fresh air for a change. I always miss my tools when I am on Windows, and while I know a good deal of PowerShell it still doesn't work for me as well as "Unixy" tools.
Looking at the available options, I like that it can display the extended attributes of the files, because I use extended attributes for various purposes.
On the other hand, it could not replace ls for me, because exa does not have any equivalent of the ls option --full-time. All the possible exa options to display the time truncate the timestamps to various resolutions (much coarser than how the timestamps are stored in the file system).
`exa -l --time-style=full-iso' truncates the timestamps to millisecond resolution.
`ls --full-time" gives the timestamps as they are stored by the file system, without alteration. For example the xfs timestamps and the FreeBSD ufs timestamps have nanosecond resolution.
https://github.com/c-blake/lc can do that and more; Indeed you can group "dot directories" differently than "non-dot directories". When I sat down to write `lc` I went through all of exas issues and features and included as much as I felt reasonable.
I never liked the graphical tree mode, though. I prefer packing as much information as possible into small real estate (like cell phone terminal screens).
https://github.com/c-blake/procs does include some "indentation" oriented tree viewing, though, and uses much of the same kind of classification-colorization as `lc`, just for process table listings (on Linux only for now). It also has "user tweakable aggregation" (kind of the reverse of listing the sub-threads in process).
Tree does have some options for file details as well, -p is the same as ls -l or and/or you can use options like -hug individually. -hugDC for dates and some coloring too.
Maybe not as great as exa but not bad for the classic option.
I realized that my function above doesn't fully show how I use it. I recommend setting your $LESS to include -F so that by default it doesn't leave pages of output in your scrollback. That way you can get a quick tree, scrollable/searchable in your pager, and then don't lose your shell context. FWIW, my $LESS is:
export LESS='-iMFx4 --mouse' # smart-case, status bar, quit 1 screen, 4sp tabs
Still defaults to the unreadable multicolumn view. Yuck! Why is this the default in ls? Why would anyone keep this awful default in another tool? It's so heinous.
I don't get why that's a problem, it allows you to see many many more files at first glance. Back when I switched from DOS (which does have the single column view as default for the "dir" command) to Linux, it was quite a revelation.
The overwhelming amount of time I don't need to see ownership/permission and modification time?
With `lc` you can have customized format strings so that you can see "size name", or "perms size name" or any subset/reordering of the report columns. And all of these are rolled up into a multi-column layout, though you can control how many columns you want with, e.g. lc -n3.
(Never mind the glob-abbreviation ability which while slow allows packing an enormous number of names per terminal row.)
Because it's unreadable, and virtually every directory has more files than fit in one screen, so you either read it in an unnatural left→right up→down direction or you read it in the natural up→down left→right direction and keep scrolling back up and down. It's just a terrible default that really has no use in a text environment.
I wish the authors thought a little bit more about the actual physicality of typing out commands. `exa` on a QWERTY keyboard is typed on one hand, across three rows, and with the weakest fingers. I guess I could put this into muscle memory, but I expect an `ls` like command to be ergonomic to some degree and I see myself making a lot of typos.
This is a basic flaw in the design of unix. The user interface is coupled to the implementation. To accomplish a task, you don't describe the task - you write the name of a program that executes that task. Once a program is named, no other program can be named that ever again.
I don’t understand the programming languages analogy, can you elaborate? One way to interpret that is “s/program/function, class or module/g“, but that sounds strange to me.
That was indeed the thrust of the analogy. Basically, we try to design programming languages so that the interface is decoupled from the implementation. A function should have an intuitive, descriptive name that reflects what it achieves, free of such terrestrial concerns as who wrote it, and when, and whether a different person decided to fix a bunch of bugs in it. But commands in Unix exist in a single-layer, permanently immutable namespace. Someone wrote the canonical 'top' once upon a time and now all evolutions on the concept must use names like "htop" and "vtop" and "gtop" and "ptop". By 2121 we'll have exhausted that namespace too, and be on to "aatop", "abtop" etc.
Good interface design is stable, even as the backend tech improves. Both a go-kart and the NASA crawler-transporter have steering wheels, because the wheel is an affordance for the human, not the machine. But on a Unix system, there's huge churn in how to do things - usually for no better reason than that it would break a bunch of stuff to change how the old way works, so better to simply add a new way. Someone wrote an improved version of grep - does that mean we get grep v2? Nope, we get "ripgrep", and old grep stays permanently...
The worst of it is, that namespace doesn't even guarantee anything! It would at least be some consolation if 'ls' worked identically on every system, but alas...
Interesting but there's no alternative presented. Any large software project typically has a fixed api that can't be drastically changed due to backward compatibility.
No reason to tie it to Unix either, other than it being ubiquitous.
That is a good thing, which I wish more package systems used. In popular programming package managers that use “semver”, bumping a major version usually breaks all of the internet and then some more. If you don’t believe it, just search for a non-trivial gulp or webpack recipes and it will come. The fact that ls is always the same (except for bsd and few non-standard options) is very useful when you plan to run your system for years+. Personally I don’t want to learn ripgrep, grep and aliases I have in my .profile are fine by me, and there is no reason for me to spend time to replace them with shiny new.
aka "lacks namespaces"... but it isn't so. The namespaces are paths and they're "linked" by $PATH. /usr/local/bin is a namespace. Is it guaranteed to be a fully qualified namesake? No. But your sysadmin (now Docker) is in charge of that. You can plan a system that forces everyone to use fully qualified nameplates, but you can't force people to use the system. That's why unix/posix/Linux remain the lowest common denominators.. by making fewer assumptions they retain a different flexibility that makes them useful for gluing together the ornery systems designed by all you planners.
one surprising interaction with ls i had recently was that it coloured files with capabilities differently, but it was pretty difficult to figure out what was going on.
so i had an executable that was behaving unexpectedly, somewhat similar to the linked write-up, which ls showed with black text on red background. for a while, until i remembered about capabilities, i couldn't figure out what the unusual colour meant. eventually i found the word 'capability' buried in https://www.gnu.org/software/coreutils/manual/html_node/Gene...
compared to that, exa seems to be a bit more obvious with its '@' indicator (it would be nice if it was documented in the man page and not just in https://the.exa.website/features/long-view) and the -@ option to print xattr/capability names.
Switching tools sure does highlight your own quirky usage of a tool. I installed exa and aliased it to ls, probably mistake number one.
I tend to look for things using reverse sorting a lot, and exa -ltra exa -lSr don't work out of the box (not sure why I thought it might, maybe because exa -la did) - And now I'm faced with reading a man page or documentation for some 15-20 seconds which I can't be bothered to do, despite that seeming so simple :)
I do think I'll try to give it a shot, it looks quite nice.
104 comments
[ 9.4 ms ] story [ 183 ms ] threadHigh load average, full swap, memory leaks, those things still happen today.
> exa, by default, runs the stat system call on every file it encounters.
99% of ls's use case are: show me the files in this folder.
What happened to KISS (Keep It Simple, Stupid) and the UNIX philosophy (do only one thing, but do it well)?
> 256-colour terminals are everywhere.
Laughs with Windows Terminal.
> ls is still there if you need it.
Thank you, I will keep using it. Also "ls" for "list" is straightforward, what does "exa" even mean?
There is a reason why those programs have not changed in the last 50 years: they work, they do one thing, they do it well, nobody ask them to do more.
The new windows terminal has truecolor.
Examine
The UNIX philosophy isn't "only call one syscall", so getting more info on the files it's displaying is far game in my book.
> Here’s an example. exa, by default, runs the stat system call on every file it encounters.
So does "ls" ... for at least last 20 years. Just checked on random Ubuntu system I had -- executables and dirs are highlighted with different colors.
> exa makes heavy use of colours, treating them as opt-out rather than opt-in: it will highlight files and data differently based on their type or meaning.
So does ls -- I see colors in default install. Yes, you need an environment variable to enable this, but all the modern distros set this anyway.
So based on that page, it seems that the only thing that EXA does differently is that it upgrades ls's 16 color palette to 256 colors.
I think they need stronger motivation.
I'm still not entirely convinced that it's a must-have, but it's more than just ls with fancy colours.
Personally, I'd much rather have seen an output format like JSON as a feature instead, so you can do some easier scripting through exa and jq. I'm sure there are other tools out there to serve thst purpose, though.
I've been using `exa` for over a year now, and I use it as an alias for both `ls` and `tree`. I don't really notice any benefit compared to using `ls`, but I really prefer its tree mode over the default `tree` command. It's nice being able to use the same CLI args and have a similar output format for both `tree` and `ls`.
0: https://the.exa.website/
But the thing is, if you install any modern system (ubuntu or fedora or pretty much anything else) and type "ls", it does those two things as well! Your default config will alias ls to enable color by default, and this ls invocation will be doing stat on every page.
So anyone who knows "ls" even a bit would, on looking on that particular page, say, "Huh? That's your special feature? my ls does this already and I don't have to do anything to install it. [close window]"
To reiterate, EXA does have features that "ls" does not. It just that https://the.exa.website/introduction page does not list those features at all. If you want to convince people to switch to EXA, you better point them to a different page.
0: https://github.com/Peltoche/lsd
Each of these is a package of files in a directory.
In the last few days I've been developing "ls-like" functionality for these cards with the specific goal of listing cards that need maintenance. For instance I did a series of photographs where I printed the cards but didn't generate the web sites.
Architecturally it's interesting, particularly in that there is the selection logic, the way you display a card, and then the realization that you ought to be able to do something to a card other than display metadata for it but select the cards with the same facility you use to select them for "ls".
This won't ever replace `ls` because it's not POSIX compliant, but that's okay because I don't think it needs to be. I have run into cases where downstream packages have dependencies on non-POSIX commands which gets a little annoying, but you can always choose something else (or take it on yourself to re-implement their idea in a POSIX-compliant way), which is the whole point of open source software.
Let this creator have their fun!
exa is already several years old and has 15 K thousands stars on Github. Not to mention all the people using it that never bothered to give it a star.
https://github.com/c-blake/lc
c-blake/lc: A post-modern, "multi-dimensional", configurable, abbreviating, extensible ls/file lister in Nim
It has kind of a long history. I first did a prototype in Python about year 2000 and then a year later a re-write in C which I used for a couple of decades and then an I think pretty nice 3rd gen in Nim. (Often one doesn't really get it all layered correctly until 3rd try, even for something kinda simple like `ls`.)
Miller columns a la NeXTStep is something easy to simulate with `lc` via the glob abbreviation { paste <(lc -1m25 ../..) <(lc -1m25 ..) <(lc -1m25 .) | column } and in general the program is more like an "ls construction toolkit" than a fixed classifier/turnkey ls. But really the readme covers many more details.
Among unusual ones is "tweak" files; Got a directory that you want special defaults for? Just drop in a `.lc` file. (With some parallel hierarchy features when perms do not allow that directly.) This is sort of like Windows remembering what sorting/layout options you clicked on, but manual and opt-in (and far more general).
[1]: https://www.gnu.org/software/coreutils/manual/html_node/dirc...
This is often my biggest annoyance with command line tools that rely on dedicate fonts and private use icons. The functionality is great, but making sure you've got the right fonts installed on every machine/terminal is sometimes tedious enough that I give up on things like exa.
These days I think exa does not show icons by default, which is I think the right decision.
Never used a multi-user system with a moderate amount of files, did you? Let alone distributed filesystems.
So far I've used ripgrep, fd-find, sd, exa, bat. I care less about speed and more about ease-of-use and beautiful output. Another bonus is standardized tooling between Mac and Linux; little bsd differences have been driving me nuts since I took a job that forced me into a MacBook, but these tools solve that issue and are easy to install with Homebrew.
[0] https://lib.rs/command-line-utilities
I'm in the same boat as you - I love the the rust-based CLI tools. I would also recommend installing the GNU coreutils via homebrew (https://formulae.brew.sh/formula/coreutils). This lets you run the GNU coreutils by prefixing them with a `g`, like `gsed` rather than `sed`.
It was one of the flags for ‘ls’ in particular that made me switch. There’s a way to add the gnu coreutils to your path without the g prefix so I never even notice the difference.
This is why I just use a modern cross platform shell that has everything built in. My choice is PowerShell since I flip between Linux and Windows, Nushell is also a solid choice if you want something more Unixy.
On the other hand, it could not replace ls for me, because exa does not have any equivalent of the ls option --full-time. All the possible exa options to display the time truncate the timestamps to various resolutions (much coarser than how the timestamps are stored in the file system).
`ls --full-time" gives the timestamps as they are stored by the file system, without alteration. For example the xfs timestamps and the FreeBSD ufs timestamps have nanosecond resolution.
Unless it's different on xfs/ufs, this seems to be nanosecond resolution to me,
I never liked the graphical tree mode, though. I prefer packing as much information as possible into small real estate (like cell phone terminal screens).
https://github.com/c-blake/procs does include some "indentation" oriented tree viewing, though, and uses much of the same kind of classification-colorization as `lc`, just for process table listings (on Linux only for now). It also has "user tweakable aggregation" (kind of the reverse of listing the sub-threads in process).
(I have to manually specify a bunch of git-ignores because Exa's git ignore support doesn't work properly.)
Maybe not as great as exa but not bad for the classic option.
et() { exa -alT --git -I'.git|node_modules|.mypy_cache|.pytest_cache|.venv' --color=always "-L${1:-1}" | less -R }
commands would now be, e.g. "et 2" instead of "et2", but will work with any number. defaults to 1 if just "et" is run with no argument.
I realized that my function above doesn't fully show how I use it. I recommend setting your $LESS to include -F so that by default it doesn't leave pages of output in your scrollback. That way you can get a quick tree, scrollable/searchable in your pager, and then don't lose your shell context. FWIW, my $LESS is:
Also should mention https://github.com/Canop/broot as a good directory explorer tool.The overwhelming amount of time I don't need to see ownership/permission and modification time?
(Never mind the glob-abbreviation ability which while slow allows packing an enormous number of names per terminal row.)
(available packaged in most linux/bsd distributions)
Imagine if programming languages worked that way.
Good interface design is stable, even as the backend tech improves. Both a go-kart and the NASA crawler-transporter have steering wheels, because the wheel is an affordance for the human, not the machine. But on a Unix system, there's huge churn in how to do things - usually for no better reason than that it would break a bunch of stuff to change how the old way works, so better to simply add a new way. Someone wrote an improved version of grep - does that mean we get grep v2? Nope, we get "ripgrep", and old grep stays permanently...
The worst of it is, that namespace doesn't even guarantee anything! It would at least be some consolation if 'ls' worked identically on every system, but alas...
No reason to tie it to Unix either, other than it being ubiquitous.
and that looks like a recent change, as in 2012 someone complained that ls didn't distinguish those at all: https://utcc.utoronto.ca/~cks/space/blog/linux/LsShowCapabil...
so i had an executable that was behaving unexpectedly, somewhat similar to the linked write-up, which ls showed with black text on red background. for a while, until i remembered about capabilities, i couldn't figure out what the unusual colour meant. eventually i found the word 'capability' buried in https://www.gnu.org/software/coreutils/manual/html_node/Gene...
compared to that, exa seems to be a bit more obvious with its '@' indicator (it would be nice if it was documented in the man page and not just in https://the.exa.website/features/long-view) and the -@ option to print xattr/capability names.
I tend to look for things using reverse sorting a lot, and exa -ltra exa -lSr don't work out of the box (not sure why I thought it might, maybe because exa -la did) - And now I'm faced with reading a man page or documentation for some 15-20 seconds which I can't be bothered to do, despite that seeming so simple :)
I do think I'll try to give it a shot, it looks quite nice.
I use `exa` instead of `ls` on Linux - https://news.ycombinator.com/item?id=26559334 - March 2021 (51 comments)
Exa – A Modern Replacement for Ls - https://news.ycombinator.com/item?id=20564000 - July 2019 (6 comments)
Exa – A Modern Replacement for Ls - https://news.ycombinator.com/item?id=19342031 - March 2019 (1 comment)
Exa – a modern replacement for ls - https://news.ycombinator.com/item?id=18658211 - Dec 2018 (2 comments)
Exa, a modern replacement for ls - https://news.ycombinator.com/item?id=14923362 - Aug 2017 (403 comments)
Show HN: Exa, a replacement for ls written in Rust - https://news.ycombinator.com/item?id=9087108 - Feb 2015 (87 comments)