I <3 bin/bash - An Introduction

For anyone looking to get started in software development or operations as it is pretty much a requirement that no matter whether you favor Windows, Mac, or Linux that you'll need to forge an intimately familiar relationship with a Unix style terminal.

quinn@FingerSkilletII $  i <3 bin/bash
-bash: 3: No such file or directory

Your terminal, or shell as it is also called, may or may not love you back. It all depends on how much time and effort you are willing to put into it, like any other relationship :)

This is the first of a series of blog posts that are going to help you feel more comfortable in a Unix-style shell. By the time you are through, and with practice and time, you'll be able to comfortably navigate around in a Unix terminal. Awesome, right?

Setting up your terminal

Windows Users

Since Windows isn't a Unix based operating system, the fastest way to start playing around with Unix commands on your Windows machine is to install Git BASH for Windows. If you're unfamiliar with git and/or version control: don't worry about that right now. While it is a topic you'll need to familiarize yourself with later and you will need to know how to use git at some point, for the purposes of going through these exercises you'll just be making use of the Unix style commands that they ported for Windows.*

Mac Users

macOS is a Unix based OS, so for the purposes of this tutorial you already have almost all the commands you need!*

Optional (but strongly encouraged): install Homebrew.

Why Homebrew? Basically, it allows you to quickly download command line tools via brew install and easily keep them updated via brew update which is a huge benefit. Most, if not all, of the tools you can install via brew can be downloaded and installed manually, but when you go to update them you will have to go through the same process every time for each one. After a while it can be hard to keep track of what you've downloaded and what needs updating, so it's very easy to let things get out of date. brew update will search for updates for anything you've installed with brew, so in that regard keeping things updated is super-easy.

There are a few Unix based commands that I'll touch on over the course of the tutorial that do not come by default with macOS, so please install the following:

brew install wget tree ack

Linux Users

Linux is also Unix based and you already have a package manager built-in, probably either yum or apt-get, so you're pretty much set. If you don't have tree or ack installed, please install those now using the command that matches your system:

sudo yum install tree ack
sudo apt-get install tree ack

Although most distributions of Linux just install with either of the above, if neither of the commands above work for you please take a look here for how to install ack on your distribution.

* Non-Linux users: there is also the option of setting up a Linux environment on your machine with with what's called Vagrant. I'm not recommending that here because 1) that's a whole different set of tutorials and 2) one purpose of this tutorial is to help you learn how to use your command line environment in a relatively standard way.

Who and What: Users

The first and possibly easiest thing to understand about your system is that it has users. Typically there is an admin account and one or more user accounts, e.g. jaynec. On Unix based systems it is important to know that there is also a root user that is basically a "super administrator".

  • Upside: you can do literally anything as the root user.
  • Downside: there is no guarantee that you will necessarily be prompted even if you are about to do something with serious consequences.

The way to run commands as root is sudo <cmd>, for example:

quinn@FingerSkilletII $  whoami
quinn

quinn@FingerSkilletII $  sudo whoami
Password:
root

You can see that when I tried to run the same command as root I was prompted for my user password and that my user showed as root rather than quinn.

Now that you know a little about who root is, it's worth taking a look at my prompt. You can see that before the whoami command there's quinn@FingerSkilletII $. quinn is my username and FingerSkilletII is what is called the hostname, which for all intents and purposes can be thought of as the computer's name. The $ is the default way to end a prompt, although if you were to switch users to the root user (as in actually logging in as root and not just using sudo <cmd>), then the $ would change to a # by default. This is important to notice when reading the commands and terminal output that people paste online. To switch to another user:

quinn@FingerSkilletII $ sudo su work
work@FingerSkilletII $

Depending on your system you may be able to run the su command not as root. To log out of this session, hit cmd+D (or ctrl+D for Windows users). To log in as root you use the same command without supplying the username:

quinn@FingerSkilletII $ sudo su
root@FingerSkilletII #

Note that in order to switch users to root you will need to run su with sudo.

Back to whoami - did you take a moment to research the command before running it? If not, this is the perfect time to start learning that habit.

For practice, rather than taking my (or the internet's) word for what commands do, we'll be using the command's manual:

quinn@FingerSkilletII $  man whoami

WHOAMI(1)                 BSD General Commands Manual                WHOAMI(1)

NAME
     whoami -- display effective user id
...

To scroll use your arrow keys or spacebar. When you're done, hit q to quit.

As you get more familiar with the commands available to you, you might find that you need to reference the manual less and less. No matter what though, you should always take a moment to analyze what a command is doing before you run it - especially if you're going to be running it as root (sudo <cmd>).

You can also find manual entries of other commands that reference the command you are running. Try running man -k whoami to take a look at what commands reference whoami.

Review

  • User accounts vs root, the "superadmin" account
  • whoami: how to figure out what user you are logged in as
  • man <cmd>: access the manual for a specific command
  • use q to quit
  • use arrow keys or your spacebar to scroll
  • use -k to find manual entries that contain the command you provide
  • sudo <cmd>: run a command with root privileges
  • less: spoiler, to be revealed when we cover text files. Though you could man for it ;)

Directories

On a system there are directories (or folders) that contain files. To get started, let's make a few directories and view their contents:

quinn@FingerSkilletII $  mkdir astro

quinn@FingerSkilletII $  mkdir astro/astronomy

quinn@FingerSkilletII $  mkdir astro/astrophysics

quinn@FingerSkilletII $  ls
astro

quinn@FingerSkilletII $  cd astro/

quinn@FingerSkilletII $  ls
astronomy  astrophysics

To review: we made the astro directory as well as its subdirectories astronomy and astrophysics. To list the contents of the astro directory we used the ls command and we were able to change directories with cd. Notice that ls <directory> gives you the contents of the directory <directory>, but ls with no directory gives you the contents of your current working directory.

Not sure where your current working directory is? Have no fear! You can find out with the pwd command, which stands for print working directory (print like "print to screen" rather than "print to printer"):

quinn@FingerSkilletII $  pwd
/Users/quinn/blog_post/astro

The pwd command outputs the full path or absolute path, which of relevance right now includes /Users/quinn. ~ is shorthand on Unix systems for your home directory, so if you ever want to change directories to your home directory or one of its subdirectories you can use cd ~ or cd ~/<rest>/<of>/<path. This is called a relative path.

A relative path isn't just restricted to your home directory: it's whenever you base a directory's location on another directory. An example of this is when you describe your neighbor's flat/apartment: you could say "it's the apartment next to mine" (relative) or "its address is 221B Baker Street" (absolute).

Besides using your home directory, there are other ways of making a relative path. Try running this:

quinn@FingerSkilletII $  cd ..

That command moved you "up" one directory relative to your current directory. You should now be in the ~/blog_post directory (or your equivalent). To play around with this a little bit, change directories into astro/astrophysics and:

quinn@FingerSkilletII $  pwd
/Users/quinn/blog_post/astro/astrophysics

quinn@FingerSkilletII $  cd ../../

quinn@FingerSkilletII $  pwd
/Users/quinn/blog_post

quinn@FingerSkilletII $  cd -

quinn@FingerSkilletII $  pwd
/Users/quinn/blog_post/astro/astrophysics

As you can see, you can stack the .. to go up as many directories as you like. Since the full path of astrophysics has 4 parent directories, I can nest .. up to 4 times in this case. I used cd - to return to my last location, which in this case was just to go back into astro/astrophysics.

Moving on, if you wanted to create and view a parent directory and its subdirectories you don't need to cd into the directory to do so. Check this out:

quinn@FingerSkilletII $  mkdir -p astro/astronomy

quinn@FingerSkilletII $  mkdir -p astro/astrophysics

quinn@FingerSkilletII $  tree
.
└── astro
    ├── astronomy
    └── astrophysics

3 directories, 0 files

A lot faster to get to the same point, yeah? So to review, the -p flag tells mkdir to create the parent directory if it doesn't exist. To see what happens without the flag when it doesn't exist, try running mkdir newdir/subdir and see what happens :)

The tree command prints out all subdirectories and their contents - so if there were files here they'd display as well. tree can be superuseful but take care: the output may spike your blood pressure if you run it in a directory with a lot of subdirectories and files.

Now to clean up: to delete an empty directory you can use rmdir, but if you have items in your directory as we now do you'll need to recursively remove them with rm -r. We'll see this command again in the next post about files, but for now:

quinn@FingerSkilletII $  rmdir astro/astronomy

quinn@FingerSkilletII $  rm -r astro

What just happened: rmdir astro/astronomy deleted the empty directory astronomy, but rm -r astro deleted astro and all it's subdirectories and contained files. In this case, that was only the empty subdirectory astrophysics.

Review

  • mkdir: make a directory
  • use -p to create a parent with its subdirectories
  • ls: list the contents of a directory
  • cd: change directories
  • What does cd ~ do?
  • What does cd ../.. do?
  • What does cd - do?
  • pwd: basically, "whereami" or print working directory
  • tree: prints a directory and its subdirectories
  • What does tree ~ do?
    --> Protip: figure out what the command does before you run it. Author is not responsible for command output that overtakes your terminal (/) (°,,°) (/)
  • rmdir: remove an empty directory
  • rm -r: recursively remove a directory and its contents

Level-up

Did you know that you can use your tab key to autocomplete directory (and file) names? Give it a try! Note that it can only complete what is unique, so if you enter ast and have astronomy and astrophysics directories, it'll complete to astro, but if you enter astron tab will complete to astronomy.

Review

So we've covered a lot in this post. When you're ready, please hop into the next post on how to use files (link forthcoming).

Convenient Command List

  • whoami: how to figure out what user you are logged in as
  • man <cmd>: access the manual for a specific command
  • use q to quit
  • use arrow keys or your spacebar to scroll
  • use -k to find manual entries that reference
  • sudo <cmd>: run a command with root privileges
  • less: spoiler. maybe try man less?
  • mkdir: make a directory
  • use -p to create a parent before its subdirectories
  • ls: list the contents of a directory
  • cd: change directories
  • pwd: basically, "whereami" or print working directory
  • tree: prints a directory and its subdirectories
  • rmdir: remove an empty directory
  • rm -r: recursively remove a directory and its contents
  • Use tab to autocomplete the name of a file or directory.

And now you've definitely earned a:

Hot Chocolate Break
mug source

Keep practicing!