Notes on the command line || WTH is $PATH?

Notes on the command line

A good friend of mine is starting to work with the command line a little more often. These are reference notes for her, me, and anyone else that finds them useful.

What is the command line

In order to move files around, open applications, or complete any other task on a computer, you have to give the computer a command. To do this you have to use an interface that allows a user to work directly with a computer’s operating system. This is called a shell.

Your computer desktop is one example of a shell. The desktop is a graphical user interface (GUI) shell that is visual and user-friendly. It is designed to be relatively foolproof. For example if you delete a file on the desktop and then realise a minute later that you meant to keep it, you can usually retrieve it from the trash.

The command line or command-line interface (CLI) shell is much more bare-bones. With the command line, you give commands to your computer directly by entering lines of text. It does exactly what you tell it to which makes it efficient, powerful, and potentially dangerous. For example, you can run rm *.jpg to delete all of the JPG files in your current directory (folder). If you accidentally run rm * instead though, you’ll delete every file in the directory. This is permanent and unless you’ve got a backup, you won’t get those files back.

Since the desktop provides a great UI for most purposes, the command line isn’t used by most computer users. That said, it is needed to install or control certain software such as Git or NVM so is often used by people that work with code.

How to use the command line

Most consumer computers come with a default application for the command line. Mac computers come with Terminal (find it in /Applications/Utilities/, and newer versions of Windows have Windows Terminal.

To run a command in an application like Terminal, you have to use a particular syntax. If you use the wrong syntax, this may result in an error or unintended consequences. The exact syntax depends on your operating system and the software you are trying to use.

Use caution when running commands, as mentioned above they can really do a number on your machine. Only run a command if you understand what it is going to do, and pay attention to a command’s output. Certain commands, particularly those involved in an installation process, might have very important information regarding next steps or warnings.

Most importantly (not just in relation to the command line): make sure you have a good, recent backup of your computer! You will need this if something goes wrong.

There are a lot of great tutorials online regarding syntax and commands, see the resources at the end of this post for some useful reference material.

How the command line is configured

Each time you open a window in your CLI, the CLI sets up a shell instance according to configuration scripts. On a Mac, the system-wide configuration script files are in the directory /etc, and the values in these files may be be overridden by the configuration scripts in the user’s home directory ~/.

The default command line shell on a Mac is /bin/bash. This is why “bash” is within a lot of the shell configuration file names. The exact user config file that gets loaded depends on the nature of the shell instance, but I’ll refer to .bash_profile for the remainder of this note since that is the file that gets loaded by Mac OSX Terminal by default.

The .bash_profile is sometimes edited automatically as part of another command. For instance when you install NVM, the installation script will automatically add the necessary NVM configuration lines to the the appropriate user config file.

You can also manually edit .bash_profile. You might do this if you want to customise the shell a bit (see the resources section of this note) or if you need to sort out something that went a little wrong when it was edited automatically. If you do edit your .bash_profile, be careful! Screwing up this file can break your whole CLI. Don’t replace your config files (.bash_profile or any other, for that matter) willy-nilly with someone else’s version that has been shared online. Your version may have some important values already in place, so you should only add the values that you need and fully understand.

When editing shell configuration files manually or as part of another command, remember that your changes will not take effect in existing shell instances. That is because the shell configuration happens before the instance is loaded, and it doesn’t happen again unless you explicitly give it that command. After you make shell configuration changes, it’s best to load a new shell instance or run source ~/.bash_profile in an existing shell instance to load the updated file. If you make a lot of changes and something is screwy, you might want to consider restarting your computer since your desktop is basically a shell instance with a GUI.

Paths and why $PATH is important

A path is a line of text (a.k.a. a string) that identifies a location within a file system. One example on a Mac might be ~/documents; that is the absolute path to your user’s Documents folder.

A path can be absolute or relative. Absolute paths start with / (the root of the whole file system) or ~/ (the home directory). If, for example, you ran the command cd ~/sites to change directories, it would take you directly to your user’s Sites directory.

Relative paths don’t start with anything and lead on from your current directory. So for example on a Mac, if you want to run cd sites to change in to your Sites directory, your current directory has to be your home directory ~/. If it’s not, you would get an error such as No such file or directory.

$PATH is an environment variable. A variable is a short string that is assigned a value that can be referenced and manipulated. More specifically, $PATH is a variable that is assigned by the system and user configuration scripts when the shell is set up, and the $PATH contents are a long string of absolute paths separated by colons.

To see what’s in your $PATH in Terminal, run echo $PATH. It should return something like:

/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

Each of the absolute paths within the $PATH contains important executables, or files that perform a particular task. If your shell instance is behaving weirdly – for example, commands aren’t working when you know you’ve installed the related scripts – the problem may be that a directory is missing from the $PATH.

Further reading

All the above just barely scratches the surface. Here are a few additional resources that I’ve come across and like:

  • Dave Baumgold’s “Getting to know the command line” is well-structured and includes a lot more detail about syntax, how to move around, and shortcuts.
  • Apple’s Command Line Primer outlines useful concepts and frequently used commands in a slightly more technical way, but still beginner-friendly.
  • Mark Otto’s .bash_profile in his config repository is a great reference if you’re interested in customising your Terminal window a bit. Lines 1–14 are particularly great, they add the current working directory and Git branch to the the PS1 (the primary prompt displayed before each command). It helps you be sure of where you are and what you’re working on, and it relays this to you in lovely ANSI colours. If you work with Git on the command line a bunch, the colour suggestions in his Git configuration file .gitconfig are very worthwhile. Thanks to SB for bringing Otto’s repository to my attention!
  • See this app which automatically suggests the correct command if you screw one up. Alias to please or something similar to make SFW. Requires pip, python, and python-dev. Came across this via @sarah_edo, alias suggestion made by @kayandraJT in the replies.
  • See Jeffrey Paul’s “Stupid Unix Tricks” for further tips, more on the intermediate/advanced end of the spectrum I’d say but very worthwhile.
  • Koen Van Impe has a short primer on different shell types (2014) including interactive, non-interactive, and login shells.
  • Dave Rupert’s guide to webdev on Windows (2018) would absolutely be my go-to-first guide if I was thinking of switching to Windows.

I’d love to hear more from others if anyone reads through this and has suggestions.


Edit 17.10.19 – Added Jeffrey Paul Unix tricks links; clarified some info about $PATH.