|
Command-Line Antipatterns
|
In traditional command-line environments, as people have
attempted to make programs for the environment more
user-friendly and capable, the result has been that these
programs have assumed burdens which, I believe, ought to be the
domain of the shell environment itself. Here I will provide
some examples of this.
- Replication of Command Environment
In some programs, such as ftp, functionality of the command
shell environment is replicated in order to provide an
environment similar to the command shell, but with the
addition of the functionality the program provides. This
solution is used because in most CLI environments, there are
no good mechanisms for interacting with an ongoing or
persistent process. Such mechanisms do exist at other levels:
for instance modern GUI applications typically include
programmable interfaces, allowing them to respond to requests
from other programs. However, the availability of these
mechanisms is not exploited for use in interactive command
sessions: mostly it is intended for use in scripting. While
the challenge of writing a program that replicates the command
environment is greatly simplified by reusable libraries, this
replacement environment generally is not written to be fully
equivalent to the environment the user was using. As a
result, while using the program the user must adapt to the
style of a different command shell, and deal with its
limitations and idiosyncracies.
- Pseudo-Persistent Programs
In response to the problem of environment replication, other
problems attempt to create the experience of interacting with
a persistent program in the normal command shell by making the
program's functionality available through commands accessible
in the normal shell, and retaining program state between
operations, in order to provide transparency for the user.
This approach works, but it is complex to implement and
limited in capabilities. For instance, the command shell
generally has no way to assist the user in using these
commands (a custom command shell-operated program could
provide tab completion, for instance, but the general-purpose
command shell knows nothing about how to tab-complete names of
files on a remote FTP site, for instance, or the names of
options that can be supplied to a command.) Additionally,
this approach doesn't lend itself particularly well to
multiple sessions of the program operating simultaneously.
This sort of technique is at best a rough approximation of
functionality that could be provided by an object-oriented
environment.
- Divergent Syntaxes for Common Operations
One of the simplest operations that can be performed is the
lossless conversion of one file type to another. For
instance, take a GIF image and store it in a PNG file, or take
WAV audio and encode it as a FLAC file, or take an
uncompressed file and compress it with gzip, info-zip, arc,
arj, rar, etc. Utilities for converting between formats are
generally easy to come by: the problem is that typically each
of these provides its own means of doing basically the same
thing. This is basically a standardization issue, and could
be resolved simply by establishing command-line UI guidelines
and making these programs conform to them. However, I believe
that, to the user, the important point isn't what program
does the conversion, or how to run that program, the important
point is that the conversion happens. The relevant aspect of
the existence of each of these programs is that they
provide mechanisms for a particular set of translations. So
long as the available translations and the code to perform
them are known, the shell itself can mandate the syntax for
translation.
Mail GEC