Understanding Shells: Concepts & Terminology

Shells play an important role for most people that use computers and an even larger role for software engineers. Depending on past experience one may be using a shell without a comfortable understanding of shells. This is my take on the basic concepts. Other posts may follow, diving deeper into technical specifics of how to use various shells.

For a summary of the most important concepts you can jump to Key Ideas.

Understanding the concept of an operating system will help us understand the concept of a shell. An operating system is a program that manages a computer’s resources. The resources managed by the operating system will include memory, storage devices, input devices (such as a keyboard or mouse1), displays, and other hardware. When an application saves a file to storage, needs more memory, needs to change what’s being displayed, the application makes those requests of the operating system. When a person presses a key on the keyboard or clicks a mouse button those interactions first go to the operating system. The operating system then sends the information to the shell.

A shell is software that is an interface for a human being to interact with the operating system. That is, a shell talks to the operating system on the behalf of a human being. Menus, buttons, command-line prompts, etc. are all elements of the shell. Keyboard interactions, mouse movement, mouse clicks, and other input are all sent to the shell by the operating system. Based on that information, the shell might request the operating system:

  • change the display (different menu, close a window, etc.)
  • launch an application
  • close an application
  • save, copy, or move a file
  • etc.

There’s a variety of ways a shell can perform its job of translating between the person using a computer and the computer’s operating system.

On a graphical user interfaces (GUI), a person interacts by using a combination of a pointing device to interact with images/icons/graphical parts of the interface. The person may use some form of a keyboard to supplement the graphical interactions. Anyone using iOS, Microsoft Windows, macOS, Android, etc. will be familiar with this type of interface.

On a command line interfaces (CLI)2,3 a person interacts with the shell by typing commands on a keyboard. The earliest4 shells were all CLIs due to the limitations of the technology of the time. If you’ve used the Windows Command Prompt, Windows Power Shell, or macOS’s Terminal, you’ve used a command line interface (CLI).

While the defining characteristic of a shell applies to graphical user interfaces (GUIs), they’re usually not called shells. In common usage the term shell is almost always referring to a command line interface shell — very often those shells developed for Unix/Unix-like systems. Normally, people will use the term GUI5 for graphical shells.

As with a lot of software, many different shell programs have been written over the years. Here are some of the shells currently in use:

NameFull Name
shBourne shell6
bashBourne-again shell
cshC-shell
tcshTENEX C-shell
kshKorn shell
zshZ-shell
… and many others …

While many of the shells have commands and syntax in common they all will also have commands and syntax the others do not. Each shell is effectively its own mini “language” for communicating (and in many cases, automating) with a computer.

With these concepts in mind, we can look at familiar platforms and identify how they fulfill those roles.

Microsoft Windows includes both an operating system and GUI — specifically Explorer7. However, the GUI isn’t the only shell that is included with Microsoft Windows. There are two CLI shells included: Command Prompt and Windows Powershell. Software engineers who have installed Git for Windows will usually have Git Bash for Windows as well. Git Bash is a Windows version of the shell bash.

Apple’s macOS includes an operating system (macOS itself) and a GUI (Aqua). Because macOS is a Unix/Unix-like operating system it is able to use any of the CLI shells available to Unix/Unix-like operating systems. In addition to Apple’s GUI, a few CLI shells come preinstalled: bash, ksh, sh, tcsh, and zsh. Depending on macOS version, others may be installed. The “default user shell” through 2019 was bash. After 2019, Apple began moving toward making zsh the default.

There’s one more concept that will help when discussing CLI shells. There was a time when the hardware used to communicate with a computer was called a terminal. Many of the CLI shells for Unix were originally developed during that time period. Many of the features of the CLI shells that depended on how the hardware terminals worked are still built into those shells. Because of this, the shell is usually run in a terminal emulator — a program designed to emulate the hardware terminals. In everyday conversation, terminal emulator gets shortened to terminal or term. On macOS, the emulator is simply named Terminal. For people using Git Bash for Windows the emulator is internal to Git Bash — that is, Git Bash is both a terminal emulator and a shell.

IntelliJ has its own terminal. On Microsoft Windows, the default IntelliJ shell is Powershell. On macOS, the default IntelliJ shell is sh.

Some terminal emulators are combined with networking clients so that they can be used to connect to servers remotely over the network. Terminal emulation is often essential for these clients because the remote server will want to run one of the CLI shells.

Key Ideas

  • A shell is any program that handles translating input from a person into something that a computer’s operating system can understand.
  • Common usage of the term shell usually refers to the CLI shells used on Unix (or Unix-like) operating systems, such as bash or zsh. It’s rare for someone to call a GUI a shell even though the term applies.
  • Each shell has its own “language” for a person to use when communicating with the shell.
    • With a GUI, the language is a set of visual metaphors (such concept of a window) combined with input from mouse & keyboard.
    • With a CLI, the language is a set of commands that are typed into the computer at a prompt.
  • A terminal historically was a piece of hardware. Today, terminal or term is a program that emulates the behaviors of the hardware terminals.
  • Git Bash for Windows is both a terminal emulator and a shell.
  • IntelliJ has a built in terminal whose default shell is either Microsoft Windows Powershell or sh

References & Related Pages


  1. While keyboard and mouse are the most common, there are many kinds of input devices: touch screen, eye-tracking device, touchpad/trackpad, digital stylus, trackball, … 

  2. Another term for the same concept is character user interface (CUI). While CUI nicely parallels GUI, Command line interface (CLI) is more widely used. 

  3. In addition to CLI, there’s a rarely used term text-based user interface (TUI) this refers to an interface that is like a graphical interface but the “graphics” are composed of letters, numbers, and symbols. 

  4. The first Unix shell, the Thompson shell, was written in 1971. 

  5. Pronounced like the word gooey. 

  6. Historically ‘sh’ also was the name of the Thompson shell. Bourne’s shell replaced Thompson’s but they both had the executable name ‘sh’. 

  7. Not to be confused with Internet Explorer nor Windows Explorer (recently renamed to File Explorer). Internet Explorer is a web browser, Windows/File Explorer is a file manager, and Explorer is the shell. There’s complicated history behind why all three are named explorer which is even more of a distraction from the main topic than this footnote. 

Create React Application with Typescript, Enzyme, and Sass

This is just a set of notes on what was required to set up this combination of packages in create-react-app (CRA).

In your preferred shell for working with node:

// Shell/Console/Command Line

# create CRA application with typescript
npx create-react-app context-example-application --template typescript 

# Update an fuzzily matched dependencies
npm update

# commit any updated dependencies
git commit -m "Update dependencies"

# List other outdated dependencies. To actually update, one will need to edit
# package.json to enter the new versions.
npm outdated
...
# Install dependencies whose versions we've changed
npm install

# commit the updated dependencies
git commit -m "Update dependencies" # commit changes

# Add Enzyme
npm install enzyme enzyme-adapter-react-16 @types/enzyme @types/enzyme-adapter-react-16 jest-enzyme

To avoid some repetitive configuration in each test file, one can add the imports and setup for Enzyme to setupTests.ts:

// setupTests.ts
...
import {configure} from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import 'jest-enzyme'

configure({adapter: new Adapter()})

I briefly considered adding import {shallow, mount, render} from ‘enzyme’ as well, but it felt like a bridge too far, since I’d potentially be importing more than was needed for a given file. So I landed on doing that import in the individual files.

Installing sass is easy:

// Shell/Console/Command Line

npm install sass

That installs sass which is a node wrapper around Dart sass. There’s potential pitfalls with the other options (dart-sass, node-sass). Carter Bancroft makes some compelling arguments for using this node library over the others: https://carterbancroft.com/sass-and-webpack/

There’s an example application of this setup on GitHub at: https://github.com/iain-davis/create-react-app-typescript-with-enzyme-sass

What’s In A Byte?

When it comes to computer memory and computer storage the unit we use for measuring size and capacity is a byte. If I was talking about a file I might say “This file is 28 bytes”. If I’m talking about a computer’s memory capacity, I might say something like “This computer has 28 bytes of memory”. Or if I’m talking about a storage device such as a hard drive, I might say “This hard drive has 28 bytes of storage.”

Okay, sure, a byte is a unit of measure for computers. But what is it really? Depending on who you ask, you might be told “a byte is the memory (or storage space) taken by one character” or “a byte is 8 bits”. Of the two, I think the first definition, “a byte is the memory (or storage space) taken by one character”, is easier to wrap one’s thoughts around, so we’ll start there.

A byte is the minimum amount of memory (or storage space) that a character uses. Or to put it more clearly: A character requires at least one byte of memory or storage. There are kinds of characters that use multiple bytes, but I’m saving that topic for another post.

Thinking of bytes in the context of characters won’t help our understanding unless we have a common understanding of what computer geeks mean by a character1. All the letters, numbers, symbols, punctuation, even spaces are all characters. The letter ‘a’ is one character. The percent symbol, ‘%’, is another. The digit ‘1’ is yet another. Each of these characters will require 1 byte of memory or storage.

The sentence ‘Iain counts’ is 11 characters — Iain is 4, counts is 6, and the space is 1, totaling to 11 characters. The sentence also requires 11 bytes of memory or storage.

There are also some special characters, usually not displayed on the screen. These characters are used in various ways, such as marking the end of a line, the end of a paragraph, one is used to represent “tab”, etc. Each of these special characters will require 1 byte of memory or storage when they are used.

In theory, one can count up all the letters, numbers, symbols, punctuation, spaces, and the special characters in a document and that will be the size of the document in bytes. However, that is only true for plain text. Plain text lacks formatting (italics, bold, fonts, font sizes, etc.) of any kind and plain text doesn’t have any characters that require more than one byte. And it is, well, text.

Text that is not plain, such as documents produced by word processing software (such as Word, LibreOffice, Wordperfect, Google Docs, etc.), will have a much larger size in bytes. This is because all the formatting information will be included in the file. Even a relatively small will have a lot of such information. For example, the sentence, “Iain counts” saved from Word produced a file that is 11,733 bytes.

When it comes to word processing documents, photographs, videos, movies, music, sounds, it is more difficult count up the number of bytes used. Generally, you can expect them all to be much larger than plain text. However, their size is still measured in number of bytes.

To put bytes in perspective, here are some example items and how many bytes they use:

Maximum length (140 characters) tweet content140 bytes
This Blog Post4,092 bytes
War and Peace (in plain text)23,359,546 bytes
AC/DC’s Back In Black (as a high-quality MP3)10,232,548 bytes
A typical movie in SD1,500,000,000 bytes

As you can see, the number of bytes of various kinds of data varies widely. And for some kinds of files can be quite large compared to a tweet or a blog post.

Byte is the basic unit of measure of computerized information. When we’re discussing plain unformatted text, one can assume that each letter, digit, symbol, or other character will increase the size of the information by one byte.

The next topic in this series is what “memory” and “storage” mean. Sorta obvious from the terms and sorta misleading from the terms. So clear as mud until discussed. More in the next post!

Key Ideas

  • Byte is the unit of measure for measuring storage space, measuring file sizes, how much memory programs and data use.
  • Characters are all the letters, numbers, and symbols we use.
  • Characters are also used to represent special concepts such as the end of a line, end of a paragraph, tab character, space, end of a file, etc.
  • Each character uses at least one byte of memory or storage.

  1. It is not, of course, what my great grandmother meant by character. 

  2. Thank you Project Gutenberg: https://www.gutenberg.org/files/2600/2600-0.txt