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.
- pwdprints the current (working) directory
- cdchanges the working directory
- lslist the contents of a directory
- ..denote the parent directory
- .denotes the current directory (useful, eg, when copying)
- touchupdates the access and modification times of files, but also creates a file if it does not yet exist
- mvmove (or rename) one or more files or directories
- cpcopy one or more files or directories
- rmremove (ie, permanently delete) file(s). A good alternative is to “trash” them with- mv file ~/.Trash
- mkdircreate a new directory
- rmdirremoves 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:
- catfor concatenating files; can be used to print file contents in the terminal
- findfor recursively searching a directory hierarchy returning names of files and/or directories
- wcfor counting characters, words, and lines
- headfor obtaining the first few lines
- tailfor obtaining the last few lines
- sortfor sorting the contents of a file
- uniqfor removing adjacent duplicates
More-advanced tools that deserve their own section and explanation
- grepfor matching a Regular Expression pattern in one or more files
- seda stream editor for modifying data
- awka 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)