Shell and Terminal on Mac

Abbreviated Fundamentals of the Command Line Interface

What’s what

Most users of personal computers today are intimately familiar with the graphical user interface (GUI) whereby interactions with the computer consist of using a mouse (and occasionally the keyboard) to navigate across several aesthetic applications, often clicking on visual elements such as folder icons, buttons, and menus.

Before the development of the GUI and means of interacting with the computer through these more-visual elements, there was (and continues to be) a text-based method of interacting with the computer called a command-line interface (CLI).

In the “old days,” a computer would boot into the CLI, as there was no other option. Today, each major operating system has an application that provides a CLI. This type application is called a terminal emulator (or just terminal for short). On MacOS, the app is unceremoniously named “Terminal” and can be found in the /Applications/Utilities directory. But you can download other terminal applications, including iTerm2, Warp, Alacritty, Hyper, Tabby, Kitty, Rio, or others.

Every terminal application has a text-based input field called the command prompt. When you type and submit a command at the command prompt, the Shell Command Line Interpreter (or just Shell) parses and interprets the text you have typed, carrying out your instructions and possibly returning information to you in the terminal. This Read-Eval-Print loop (REPL) is common when computer programs allow “live” interaction between the user and computer. The default shell on MacOS at the time of writing is zsh (pronounced the “Z shell”) which replaced bash (the “Bourne Again SHell”) as the MacOS default starting with the release of MacOS Catalina in 2019. bash, as evidenced by its name, was an evolution of the Bourne shell (with the short name sh). To round out the list, the only other popular shell today is fish (the “friendly” shell).

Shell Basics

First, let’s determine what shell you are using. Open your terminal application and type echo $SHELL at the command prompt. If the response is /bin/zsh then its zsh.

Most commands tend to have the following structure

[command] [options] [arguments]

You’ll need help. Often. The commands run-help and man (short for manual) following by a command name will bring up the command’s documentation using the terminal pager less. For navigation, arrow keys move one line at a time, page up/down and the spacebar move one page at a time, and q exits. For more succinct documentation, visit https://tldr.sh/ in a browser, which can be used interactively or downloaded.

Moving around

Navigating the hierarchy of directories and performing simple operations on files are fundamental to working from the command line. Note that many of the following tools take the verbose -v option, which prints a confirmation message in the terminal and is useful to “see” what these commands do, especially while learning them.

  • pwd prints the current (working) directory
  • cd changes the working directory
  • ls list the contents of a directory
  • .. denote the parent directory
  • . denotes the current directory (useful, eg, when copying)
  • touch updates the access and modification times of files, but also creates a file if it does not yet exist
  • mv move (or rename) one or more files or directories
  • cp copy one or more files or directories
  • rm remove (ie, permanently delete) file(s). A good alternative is to “trash” them with mv file ~/.Trash
  • mkdir create a new directory
  • rmdir removes directories (use with caution!)

It is often useful to use wildcards to return a “group” of files. Common wildcards include:

  • * denotes zero or more characters
  • ? a single character
  • [abc] a list of permited characters
  • [a-z] a set of characters

Combining tools

The Unix philosophy is that command line tools are designed to do one thing and to do it well. Therefore, complex operations are created through a composition of tools. This is made possible by managing the communication streams of these tools. Each has 3 standard communication streams: standard input (stdin), standard output (stdout), and standard error (stderr). Often, the keyboard will not be the source of input, but rather it will be from the output generated by other tools and contents of files.

  • < takes input from a file (eg, < file.txt wc)
  • > directs output to a file and overwrites (eg, ls > dir_contents.txt)
  • >> directs output to a file and appends
  • | pipes output from one command to input of another (eg, ls | less)

Common tools for inspecting files, or for gathering and summarizing their contents include:

  • cat for concatenating files; can be used to print file contents in the terminal
  • find for recursively searching a directory hierarchy returning names of files and/or directories
  • wc for counting characters, words, and lines
  • head for obtaining the first few lines
  • tail for obtaining the last few lines
  • sort for sorting the contents of a file
  • uniq for removing adjacent duplicates

More-advanced tools that deserve their own section and explanation

  • grep for matching a Regular Expression pattern in one or more files
  • sed a stream editor for modifying data
  • awk a data processing language named after its creators

Sections to add

  • File permissions (read/write/execute)
  • A whole section on each of grep/sed/awk
  • Connecting: ssh/ftp/curl
  • Environment variables (incl. customizing the prompt)
  • Writing programs (incl. if/for/while)