BCL -- Bob's Command Language
A fresh take on command line utilities plus a scriptable shell language. Standard, portable command lines that produce pipeable objects; standard pipe list filtering, processing and sorting; a scripting language for integrating any external command; and an overall conceptual framework to guide future work.
Integrate the unix utilities with a scriptable shell and what do you get? GNU and BASH, which are great for those who've grown up with them. Let it simmer for a while longer and what do you get? GNU command line parsing, FISH and ELVISH for "better" shells and SystemD to replace all those hacky sh scripts.
Surely we can learn from our heritage and reconcieve the whole thing.
Where we've been
unix utilities and rsh / csh
The origin story for unix™
The shell allowed pipes between utilities, expanded globs, the utilities simply processed the resulting paths, and generally did a single thing and did it well.
Everything's a file in unix, so if you have great tools for processing files (sed
, grep
), you can create some pretty powerful and elegant one-liners.
DCL "Digital Command Language"
This is really where I'm coming from. DEC had a unitied command language running on their several OS'es: RSX-11m, RSTS and RT-11 but also TOPS-10 and VMS. Each of these had a native command interpreter and different path syntax for files, too. Yet DCL established standard command names, argument parsing and a standard (though limited) scripting language.
It also standardized the configuration for wrapping native commands, something BCL should also provide.
DCL had built in, incremental help, too (IIRC).
Powershell
The granddaddy of "everything is data" and standardized verbs and nouns.
But really clunky in configuration, in error messages
Powershell has the notion of "providers", which can map collections of diverse resources into a file-system-like hierarchy so they can be manipulated by a standard set of cmdlets. Examples of the diverse resources: filesystem (duh), TEMP folder, cmd aliases, env vars, certificates(!). Not all of these are necessarily hierarchial, but you can at least enumerate them with get-children
(a.k.a dir
) and can get and set properties on them.
BCL wants to accomplish that unification but more by enabling a standard set of verbs rather than belaboring the filesystem analogy. How to deal with git
?
Powershell also has a user-extensible way of rendering the last output of a pipeline (which is always a complex object), so you can get normal looking output from a get child
command that might have many more columns than you care to see in a dir
command. This is an important concept to carry forward.
When you invoke an external command in Powershell, something transforms the stream of lines into objects. Need to look that up, it, too is an important thing to carry forward. (DCL could configure how to wrap the invocation of a native command; we'll extend that by configuring (or scripting?) how to parse the output and send it down a pipe).
Python
Great for scripting. Great for duck-typed object oriented programming. Great for dynamic extensibility. the very model of a great scripting language
I don't know how general-purpose BCL's scripting langage needs to be. You should be able to write a script that looks like a wwell-behaved BCL command:
- reads and writes the pipeline
- normative argument list
- dynamically loaded
- participates in help subsystem
Xonsh, Nushell
Both examples of recent attempts to improve shell. Xonsh stays in its lane when it comes to invoking external commands. Nushell integrates and reimpliments many common utilities (not always with perfect fingertip fidelity).
Both provide a rich completion and command line editing experience, plus rich command history. BCL should do these, but how?
Problems with where we're at
Where it all goes wrong:
- Output is just text, not structured data, so pipes are great, but sometimes the following program has an impossible job.
- formatted output makes it hard to process piped output: coloring (
ls
,grep
) (note that these encode object properties via color); tabular output (top
,htop
, not because they're curses, rather because fixed format ascii screen art means a lot of counting, de-padding...) - structured data hard to deserialize back into field names:
NB. not all formatted data is evil. Though it's hard to do, there are tools to reverse engineer MAN pages to generate completer scripts. More power to them!
2. Scripting language directly at the command line
All command shells have a scripting langage including flow control, error / exception handling, variable declaration, function definition. Most languages allow all this syntax at the interactive command line, for the ultimate in opaque one-liners.
I think this is a bridge too far. I would like the command line to be really intuitive and spur of the moment, not something you have to open your IDE (or otherwise pick up your coding form) to craft.
So maybe BCL allows the scripting language syntax only in a function definition. Command line can invoke functions. There's limited implicit flow control at the command line, such as error handling. There are built-ins for table processing: filtering and restruction, but maybe no lambda
to do ad-hoc table processing right on the command line. But a powerful function definition and invocation syntax (parameters with defaults! typed arguments with runtime checking!)...
Where I'd like BCL to go:
- [[Nushell]] Fast to load, fast to run
- [[]] Make your environment easy to discover via completion. Enumerate network devices. List configuration settings for a service (or anything else!)
- [[Python]], extendable by dynamically loaded scripts that look like