The Difference between Console, Terminal, Shell, and Command Line

When I first started out with Linux, I was confused by some of the terminology for quite a while. Specifically, refereces to the console, the terminal, the shell, and the command line are all over the place. They all seem to mean the same thing, but not exactly.

Console vs. Terminal

Back in the old days, computers didn’t have a friendly GUI (graphical user interface) where people can open up a bunch of windows and freely navigate themselves on the screen. So the main way people interact with the computer was through typing commands which will be sent to and carried out by the computer. Here the hardware device with which people interact with the computer, is called the console or terminal. The terminals had cathode ray tubes (CRTs) to display characters and some primitive graphics, typically within the limit of 24 lines by 80 chracters (you probably have wondered why many code formatting standards nowadays limit the length of one line within 80 characters, well, here’s your answer). And people used a device called teletypewriter to type their commands, shorthanded tty (looks familiar?).

While console leans more towards the physical part of the meaning, referring to actual pieces of equipment, terminal has a more electronic sense of meaning. From the Linux/UNIX point of view, everything is a file; so the operating system sees the terminal as a character device with file path /dev/ttyn. Usually the OS has several tty files so there are /dev/tty0/, /dev/tty1, etc. Through these terminals, the input from user’s keyboard and output from the system are transmitted back and forth.

Console and terminal are often used interchangeably, which take care of the text transmission part of the human-machine interaction. And now we are away from the ancient old days (for computers), we now have the concept of virtual console and emulated terminal. They basically mean that we no longer need the special, dumb pieces of equipment for input/output and they are simulated by these graphical user interface applications, which provide extra application-level functionalities. Some examples are: Konsole on KDE, Terminal on OS X and Ubuntu, Tmux and ssh, etc. There are some extra stuff going on behind the scene with emulated terminals which I won’t go into too much details (the applications have their own file handles and there are more than just manipulating the /dev/ttyn files).

With Ubuntu desktop, we usually log in to the graphial desktop environment which is hosted on one of the tty’s. And we open up a Terminal application which is a terminal emulator, to do our things. However, we can actually log onto the other ttys directly using a combination of keys, which are command-line-only (coming up later).

Shell vs. Command Line

With the text transimission in place, the shell is just a program that interprets the user’s commands and executes. For example, given a command rm -rf file1 file2 dir1, the shell knows it should execute the rm program which is supposed to remove the files and directories (with -r) provided in the argument part of this line, here file1, file2 and dir1, permanently without error messages (with -f). Another example is the cd command, which we use frequently to change our working directory. Instead of being an executable binary, the cd command is actually a built-in command provided by (almost all) the shells. Apart from executing commands from the users interactively, the shell can also execute shell scripts, which are written text of commands either shipped with the operating system (e.g., startup files) or built by developers/users (e.g., data download .sh scripts commonly seen in machine learning projects).

Since the primary use of shell is to execute programs, there’s also the concept of “environments” associated with the shell (or more precisely, a shell session) that help user to configure how they want the programs to be executed via environment variables (see this post). Some configurations are even necessary. For example, in order for the shell to execute a program (not shell builtins), the shell needs to first locate where the program is. One way is that we provide the full path to the executable, e.g., /god/knows/where/my-program <args>, and the other is to provide places that the shell can search for the program. Specifically, the PATH environment variable is what the shell will look for the paths for searching.

In all, shell hides the operating system’s kernel from the users; we rarely need to invoke system calls directly to fulfill our jobs which can be quite dangerous. That’s also why shell got its name: it protects the kernel by providing a layer for user interaction in the form of commands. Although shell has this important role in between the user and system kernel, it runs in a user process. So there are different versions of shells of our choice, e.g., the earlier Bourne shell (sh), C shell (csh), Korn shell (ksh), the most widely used Bourne again shell (bash), and the more recent and powerful Z shell (zsh). Here are two articles from the official reference manual of bash and zsh that also give good explanation of what shell is, with more jargon flying around.

What’s left for the command line is very simple: it’s just a form of interaction. Namely, typing text commands. This form of interaction is not specific to shells so we probably need to associate a “language” to it if we want to discuss something more specific. With shells, the language we use is, well, shell language, or shell scripting. With some interpreted programming languages that have interactive interpreters, like Python, the form of command line is also supported. For example, we can invoke the Python interactive interpreter with python:

dian@ubuntu % python
Python 3.8.3 (default, May 19 2020, 13:54:14) 
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello!")
Hello!
>>>

While most of these interpreted programming languages also support scripting, the command line, or command line interface (CLI) in general has the “interactive” flavor in it.

Summary

In short, these terminologies can be summarized as:

  • Console: the hardware devices for human-machine interaction by typing
  • Terminal: similar to console but can also refer to the abstract device files perceived by the Linux/UNIX operating system
  • Shell: the layer between the user and operating system that interprets commands and executes them
  • Command Line: the form of interaction by typing commands interactively

However, the boundaries between these concepts are not as strictly defined nowadays. They become blurred in that, consoles and terminals can be “virtual” and “emulated”, and the emulated terminal applications sometimes provide functionalities to complement the shell. Yet, knowing some of the nuances won’t hurt when we see a mush of these names being used interchangeably next time, right?