The CLI is the result of the evolution of a much broader human-computer interaction, specifically communication and language processing. Let’s begin the story with the creation of the first compiler, which took us from using punch cards to programming languages.
About the history
The first computer compiler was written by Grace Hopper. A compiler was able to translate written code to machine code and lifted the great burden off programmers of the time consumption of writing machine code manually. Grace Hopper also invented the COBOL programming language in 1959. In that era, punch cards were used for data processing applications or to control machinery. They would contain COBOL, Fortran, and Assembly code. The compiler and advancement of new programming languages eased the task of programming.
The same year, the microchip was invented by Jack Kilby and Robert Noyce. Much less expensive, small-scale computers were made possible and, finally, human-in-the-loop, a back-and-forth interaction between the human and computer, became feasible. Computers were now multitasking and time-sharing systems.
At this point, keyboards became the main method of interacting with computers. By the early 1960s, engineers had attached a Cathode Ray Tube (CRT) monitor to the TeleTYpewriter (TTY) machine. This combination of the CRT and TTY was called a glass TTY and marked the beginning of what we consider the modern monitor.
In 1966, the CRT and teletype machine, which combined the technologies of the electric telegraph, telephone, and typewriter, were about to merge with the final missing puzzle piece, the computer. The teletype computer interface was born. Users would type a command, hit the Enter key, and the computer would respond. These were called command-line interfaces!
There were so many more exciting developments that followed, from the invention of ASCII characters in 1963 to the internet in 1969, UNIX in 1971, and email in 1972. Lexical analysis parsers in 1975 played a major part in the development of programming languages. Text-based adventure games provided amusement for the tech savvy by 1977, and the beginnings of the GUI emerged in the 1970s.
A network of these computers would not have been possible if not for the evolution of the telephone. In 1964, the acoustic modulator/demodulator (modem) was used to transmit data between a telephone line and a computer. The acoustic modem brought us the wide area network (WAN), local area network (LAN), and the broadband we know of today. LAN parties peaked in the 1990s and carried on well into the early 2000s.
In 1978, the first public dial-up bulletin board system (BBS) was developed by Ward Christensen and Randy Suess, who also created the computerized bulletin board system (CBBS). With a modem, users could dial into servers running the CBBS software and connect via a terminal program. Throughout the 1980s, BBS’s popularity grew to fantastic heights, and even in the mid-1990s, BBSs served the greater collective market compared to emerging online service providers such as CompuServe and America Online (AOL).
Note
This deeper understanding of the history of the CLI may give you a greater appreciation for what it is. The terminal is a bit of a time machine. The use of many UNIX and DOS commands feels like you’re standing on the shoulders of giants, looking down at the long computing history beneath it.
Introducing the CLI
Based on the history of the CLI, it’s clear to see that it is a text-based interface that allows communication from user to computer, computer to computer, and computer back to user. It requires the same specific instructions and clear language as the earlier machines it evolved from. Now, let’s dig deeper into CLIs to learn about the different kinds, how they are generally structured, and how and why they are used.
Anatomy
For any CLI, regardless of the specific type, it’s important to understand the anatomy of the commands themselves. Without a particular structure, the computer would not be able to properly parse and understand its instructions. The following is a simple example that we will use to distinguish the different components of a command:
~ cat -b transcript
In the context of this example, the UNIX command, cat
, is used to view the contents of the file, transcript
. The addition of the –b
flag tells the command to print the line number next to non-empty output lines. We will go into each component of the command in detail in the following subsections.
The prompt
A symbol on the terminal indicates to the user that the computer is ready to receive a command. The preceding example shows ~
as the command prompt; however, this can differ depending on the OS.
The command
There are two types of commands:
- Internal commands are commands that are built into the OS shell, stored within internal memory, and execute faster. A few examples include folder and environment manipulation commands, such as
cd
, date
, and time
commands. They do not require a search of the PATH
variable to find the executable.
- External commands are commands that are not built into the OS and are only available through software or applications installed by other parties. These commands are stored within secondary memory and do not execute as quickly as internal commands. A few examples include
ls
and cat
. These are usually located in /bin
or /usr/bin
in UNIX and require a search of the PATH
variable to find the executable.
The previous example uses cat
as the external command.
Arguments and options
Commands usually take in parameters for input that consist of one or many arguments and/or options:
- Arguments are parameters that pass information to the command, for example,
mkdir test/
.
In the preceding code snippet, test/
is the input parameter to the mkdir
command.
- Options are flags, or switches, that modify the operation of a command, for example
mkdir -
p test/files/
.
In the preceding example, -p
is an option to make parent directories if needed.
In the example at the start of this section, -b
is an optional flag, shorthand for --number-nonblank
, which tells the command to print the line number next to non-empty lines, and the filename, transcript
, is an argument passed into the command.
Whitespace
For the OS or application to properly parse these commands, arguments, and options, each is delimited by whitespace. Special attention must be paid to the fact that whitespaces may exist within the parameter itself. This can cause a bit of ambiguity for the command-line interpreter.
Take care to resolve this ambiguity by replacing spaces within parameters. In the following example, we replace the spaces with underscores:
cat Screen_Shot_2021-06-05_at_10.23.16_PM.png
You can also decide to put quotes around the parameter, as in the following example:
cat "Screen Shot 2021-06-05 at 10.23.16 PM.png"
Finally, resolve ambiguity by adding an escape character before each space, as in the following example:
cat Screen\ Shot\ 2021-06-05\ at\ 10.23.16\ PM.png
Note
Although whitespace is the most widely used delimiter, it is not universal.
Syntax and semantics
The CLI provides the language for communicating with the OS or application. Thus, like any language, to be properly interpreted, it requires syntax and semantics. The syntax is the grammar defined by the OS or the application vendor. Semantics define what operations are possible.
When you look at some command-line applications, you can see the language being used. Sometimes, the syntax differs between tools; I will go over the specifics later in this chapter, but, for example, cat -b transcript
is a command we’ve looked at before. The command, cat
, is a verb, the flag, -b
, is an adjective, and transcript
is a noun. This is the defined syntax of the cat
UNIX command: verb, adjective, noun.
The semantics of the command are defined by what operations are possible. You can see this by viewing the options of, for example, the cat
command, which are usually shown in the usage section of the help page, which is output when a user uses the application incorrectly.
Help pages
Because the CLI is entirely text-based and lacking in visual cues, its usage may be ambiguous or unknown. A help page is essential to every CLI. To view a list of valid parameters and options, users may run the command followed by the help option, typically -help
, --help
, or -h
. The -h
option is an example of an abbreviated shortcut for the help command.
There’s a common syntax used in built-in help and man pages and following this standard will allow users familiar with the standard to easily use your CLI:
- Required parameters are typically represented within angled brackets, for example,
ping <hostname>
- Optional parameters are represented within square brackets, for example,
mkdir [
option] <dirname>
- Ellipses represent repeated items, for example,
cp [option]... <
source>... <directory>
- Vertical bars represent a choice of items, for example,
netstat {-t | -
u}
Usage
The CLI was the first interface between the user and the OS used primarily for numerical computation, but in time, its usage has expanded in many more practical and fun ways.
Let us see some of the uses:
- Editor MACroS (Emacs), one of the earliest forms of a text editor provided in UNIX, is a CLI in the form of a mini buffer. Commands and arguments are entered as a combination of key presses: either a Ctrl character plus a key or a key prefixed by a Ctrl character and the output displayed within another buffer.
- Read-Evaluate-Print Loop (REPL) is a Python interactive shell that offers a CLI, and according to its name can read, evaluate, print, and loop. It allows users a play environment to validate Python commands.
- MajorMUD and Lunatix are just a couple of popular games that were available on bulletin board systems. As soon as programmers could turn CLIs into play, they did, and while these games were entirely text-based, they were certainly not lacking in fun!
- Modern video games call their CLI a gaming console. From the console, mod developers can run commands to debug, cheat, or skip part of the game.
- Helper programs often take in parameters to launch a program in a particular way. For example, Microsoft Visual Code has a command-line option:
code <filename>
.
- Some CLIs are embedded into a web application, for example, web-based SSH programs.
- Companies such as AWS offer CLIs alongside their API as an additional way of interacting with their platform.
Last but not least, scripting has allowed engineers to take their CLIs to a more interactive level. Within a shell scripting language, programmers can script calls to the CLI and capture and manipulate output. The output of one command may also be passed as input into another. This makes the CLI a very powerful resource for developers.
Types
There are two main types of CLIs:
OS CLIs
OS CLIs are often provided alongside the OS. This kind of CLI is referred to as a shell. It is the command-line interpreter that sits a layer above the kernel interpreting and processing commands entered by the user and outputting results and a text-based method of interacting with the OS as an alternative to the graphical display.
Application CLIs
The second type of CLI allows interaction with a specific application running on the OS.
There are three main types of ways users may interact with an application’s CLI:
- Parameters: They provide input to launch the application in a particular way
- Interactive command-line sessions: They are launched after the application as an independent and text-alternative method of control
- Inter-process communication: This allows users to stream or pipe data from the output of one program into another
GUI versus CLI example
Let’s give a clear example of how the CLI can reign over the GUI in speed. Suppose we have a folder full of screenshots. The names of each contain a space and we’d like to rename these files to replace the whitespace with an underscore.
GUI
With a GUI, there’d be several manual steps for renaming a folder full of screenshots that contain whitespaces throughout the filename. Let’s show these steps within macOS, or Darwin:
- First, we’d need to open the folder containing all the screenshots:
Figure 1.1 – Folder containing the screenshots where each filename contains numerous spaces
- Second, we’d press the control button and left-click on a filename, then from the context menu that pops up, select the Rename option.
Figure 1.2 – From the context menu, click on the Rename option
- Finally, manually replace each of the whitespaces with an underscore.
Figure 1.3 – Replaced whitespaces with underscores in filename
Repeat steps 1-3 for each file in the folder. We’re lucky this folder only contains four screenshots. It can quickly get repetitive and tiresome with a folder of more files.
CLI
Let’s see how much faster the CLI can be. Let’s open the terminal and navigate to the folder with the files:
cd ~/Desktop/screenshots/
Let’s view what currently exists in the folder by typing the ls
command:
mmontagnino@Marians-MacBook-Pro screenshots % ls
Screen Shot 2022-12-20 at 10.27.55 PM.png
Screen Shot 2022-12-20 at 10.32.48 PM.png
Screen Shot 2022-12-26 at 5.24.48 PM.png
Screen Shot 2022-12-27 at 12.08.12 AM.png
Let’s run a cleverly crafted command that loops through each file in the current directory and renames it (using mv
) to translate the whitespace to an underscore:
for file in *; do mv "$file" `echo $file | tr ' ' '_'` ; done
Let’s run the ls
command again to see what’s changed:
mmontagnino@Marians-MacBook-Pro screenshots % ls
Screen_Shot_2022-12-20_at_10.27.55_PM.png
Screen_Shot_2022-12-20_at_10.32.48_PM.png
Screen_Shot_2022-12-26_at_5.24.48_PM.png
Screen_Shot_2022-12-27_at_12.08.12_AM.png
Wow! We’ve just run a single command and the files are automatically renamed! This is just one example to show the power of CLIs and how much faster tasks can be executed compared to a GUI.
The comeback
The reason there’s been a comeback of the CLI within recent years is because of these many benefits. The GUI can be resource-intensive, tedious when performing repetitive tasks, and sometimes slow.
The CLI, on the other end of the spectrum, is lightweight, scriptable, and fast. The advantages don’t end there. The CLI might even offer commands and parameters that are not available, or are unthinkable, within the GUI. There’s much to be admired and it’s also a little mysterious.
I’m crushing a little on the CLI here! Jokes aside, to be fair to the attractive GUI, it has visual cues that allow the user to be self-guided. The all-too-mysterious CLI, on the other hand, requires help and man pages to understand its available parameters and options.
Though it may appear difficult to understand, once understood, the power of the CLI becomes apparent and inspiring.