What Is a CLI Shell?
Introduction
First off, I assume the reader has some concept of what a command-line shell is. Probably you've used the DOS shell or a UNIX shell, or maybe you're familiar with the Windows options like cmd or powershell... The purpose of this document isn't to tell you that a shell is something you type commands into, it's rather an attempt to reflect on the reasons why such a tool would be a useful way of interacting with your computer.
A Programmer's Perspective
To a computer programmer, a command shell can be thought of as a particular kind of programming language. And, in fact, people do write various kinds of programs in shell languages, which allows people to automate tasks using the same set of syntax and concepts they use in their interactive sessions. One trend I find slightly disturbing is that UNIX shell languages are no longer considered adequate for writing scripts. Some of this is due to the fact that a shell's toolset consists of the programs installed on a machine - and these programs generally aren't standardized to the extent that a scripting language's API is... And some of this is due to the fact that UNIX shell languages can't easily represent certain concepts.
To a programmer, a shell is a programming language that...
- uses the state of the whole computer as its runtime environment: Files on the filesystem are a basic element of exchange on a Unix-like shell - and files on the path define the commands available to the shell. In contrast, most other programming languages treat files and other programs as foreign entities. "Native" data and commands are contained within the programming language itself, and values are generally represented in forms that can't readily be exported or understood by other tools.
- is designed for interactive sessions: A shell is designed to work as an interactive programming language, and to also provide the means to use that same syntax in a script for automation. This means that the shell can assist the user in ways that non-interactive programming languages generally can't. A user can "explore" the shell environment if they're not already familiar with what's there. They can discover commands or files and they can store and scrutinize a piece of data that's been returned. Some scripting languages such as Python or Ruby also provide this functionality. Other programming languages may provide similar functionality through a debugger. The key idea is that for the shell, interactive operation is a fundamental idea.
- ties other tools together: A basic job of a Unix-like shell is to tie different individual programs together, so they can do a job that may be too specialized for one tool, alone, to perform. For instance, if you want to download an image from a website, alter it, and then post it online with FTP: these are three distinct tasks. The typical UNIX approach is for each of the three tasks to have its own tool, and so these tools exist: wget, imagemagick, ftp... This capability is not unique, of course: one of the great strengths of PERL, for instance, is its great library of add-on modules which interface with existing libraries or implement new functionality. These libraries had to be written specifically for PERL, however, at least as wrappers: you generally can't use them in Python, for instance. This does not exactly mean that the shell command implementations are less specialized, however, just that they're specialized to a more universal environment... (So why is it that tools written for the shell aren't suitable for use in PERL as-is? Basically because most shells are too primitive in terms of their understanding and support of datatypes to be able to usefully work with moderately complex libraries: their implementation for the shell becomes excessively esoteric to work around those limitations, and attempting to map such tools into a programming language like PERL or Python becomes a headache, and the resulting tool operates inefficiently because of the means it must use to exchange data. I believe these conditions indicate a serious flaw in current command shells... A library written for the shell should be just as versatile and efficient as one written for PERL or Python, at least, and inspectable enough that they could be easily bound to other environments...)
A User's Perspective
First off, I want to clarify this point: Programmers are users, too, and I do not believe in the prevailing "wisdom" that "user" implies "unsophisticated user" or that all interfaces ought to be designed for people who don't really understand or care about computers. I am interested in writing a shell which will appeal mainly to programmers, and people who do understand and care about computers. Another way to say "A User's Perspective" here might be "The Shell as a User Interface"...
The command-line shell is a user interface that...
- communicates in terms of words, rather than images or metaphors: Commands, their arguments, filenames, etc. are generally represented as text, and usually as text that the reader can use to make some sense of what is going on. Users who don't know the name of a command can attempt to find it by guessing at what sort of words might be used for the command, and looking for commands that match those criteria. This is not entirely untrue of graphical interfaces, of course: filenames and menu options are provided as words there, too, but graphical interfaces generally don't provide a way to enter the command by typing a word. Usually the user either must find the command visually (hence, GUIs must be kept simple, so that users can find what they're looking for in a reasonable amount of time), or else by a shortcut key which, while quick and convenient, isn't necessarily easy to remember or to find. Graphical interfaces have their own ways of dealing with these problems, of course...
- allows the user to synthesize complex commands: A user can type a simple command into a shell, of course, and see what it does: but once they understand the simpler commands they can start chaining them together to perform more complex tasks. This is something that is less common in graphical interfaces: there are scripting systems which can record a sequence of menu selections or shortcut keypresses, macro systems, and options for true scripting: however, graphical interfaces don't translate readily to complex invocations where data may be extracted, passed to another tool, manipulated, re-inserted, and so on. The tools that exist which are capable of doing these things in a GUI environment generally operate on a whole different system of user interaction. Command-line shells are unique in that the style of user interaction for a simple session scales up easily to the more complex tasks.
- provides a smooth transition between interactive work and automation: Again, this is not strictly unique to command-line shells, but it is a strength of them. The formula for creating and recording complex commands incorporating decisions is the same as the formula used for the simplest commands.
George Caswell
Last modified: Thu Nov 15 17:02:28 EST 2007