Command Line Intro – Part 1

Wed Oct 26, 2016 - 1400 Words

Today we’re going to take a few steps back to cover a tool that we’ve used in every tutorial, but never actually talked about it: the command line.

Goal for this Tutorial:

  • Explore the command line shell and prompt.
  • Understand the $PATH.

When you first see a command line prompt (probably in a TV show) it can be a little intimidating. Most people imagine a mysterious, black screen with bright green letters on it. After you learn how to use the command line or shell it’s amazingly powerful, and sadly I skipped right past it when I was first thinking about tutorial topics.

Nearly every tutorial I’ve created has used the shell at some point, so it’s best that we’re all familiar with what is going on.

My Favorite Tool: The Shell

The shell is probably my favorite tool. I use the shell so much while I’m programming that it’s actually the main reason that I switched from Windows to Mac: Bash (the default shell) was too powerful for me not to use. Thankfully, today Bash is actually useable on Windows (with the anniversary update to Windows 10). Follow these instructions to install bash on Windows.

The shell is the starting point for a lot of programming tasks because you can do things in a way that is reproducible and easy to share with others. It’s hard to share what you’re doing with your mouse with someone else. It would take a long time to teach someone how to use Docker if you were only able to create containers by clicking, dragging, and hovering over items on the screen. It’s quite easy for me to tell you to type the following with confidence about what will happen:

$ docker run -it ubuntu echo "Hello, World!"

Exploring the Shell

Debatably, the most commonly used tools that your command line gives you are cd and ls. We’ve used these quite a few times up to this point. These are important because you’ll need to move around from directory to directory and see what’s around you.

We’ll use pwd to demonstrate a little of what these other two tools do. pwd *p*rints your *w*orking *d*irectory, it’s useful for when you need to see where you’re currently at.

~ $ pwd
/Users/explorer

The user that I use to make tutorials is named explorer and this output will definitely be different for you.

cd allows you to *C*hange your current working *D*irectory. Here are a few examples:

~ $ cd code
code $ pwd
/Users/explorer/code

We can see there that our working directory changed. We’ll switch back to our home folder to explore ls. To do that we can use either a full path or a relative path, either of these two lines would work:

code $ cd ..
~ $ pwd
/Users/explorer

or with the full path:

code $ cd /Users/explorer
~ $ pwd
/Users/explorer

ls is used to list out the files and directories inside of the directory that you pass it (or the current directory).

~ $ ls
Applications	 Documents Library Pictures	code
Desktop	Downloads	Movies Public	src
Dockerfile	 Dropbox Music Videos

That’s not super useful at first glance. They’re in alphabetical order by column (why not row?), but not giving us a lot of information beyond that. Thankfully, ls can take quite a few flags so that we can change the output that it gives us. The -l flag will list them out vertically and give us the permissions and last changed times.

~ $ ls -l
drwx------   5 explorer  staff   170 Sep 11 07:43 Applications
drwx------@  4 explorer  staff   136 Oct 11 17:06 Desktop
-rw-r--r--   1 explorer  staff    76 Jul 30 15:09 Dockerfile
drwx------@  3 explorer  staff   102 Jul 26 19:15 Documents
drwx------+  5 explorer  staff   170 Oct  4 08:31 Downloads
drwx------@ 23 explorer  staff   782 Oct 25 18:43 Dropbox
drwx------@ 63 explorer  staff  2142 Oct 18 20:05 Library
drwx------+ 13 explorer  staff   442 Oct  3 19:26 Movies
drwx------+  4 explorer  staff   136 Jul 30 10:08 Music
drwx------+  3 explorer  staff   102 Jul 26 19:15 Pictures
drwxr-xr-x+  5 explorer  staff   170 Jul 26 19:15 Public
drwxr-xr-x  14 explorer  staff   476 Oct 18 18:55 Videos
drwxr-xr-x   2 explorer  staff    68 Oct 25 19:12 code
drwxr-xr-x   4 explorer  staff   136 Jul 28 07:35 src

Much more useful. The version that I usually use also includes the -a flag so that I can see hidden files. This can sometimes return you a lot of files though, but the extra ones are normally hidden, you likely won’t see them in Finder.app on Mac or Windows Explorer.

Where Do These Commands Come From?

One question you might be asking yourself is “Where does ls come from?“, and that’s a great question. One of the biggest reasons that I think the command line seems strange at first is because there is a lot that isn’t shown to you unless you ask.

We can see where a specific command comes from using the which command. Let’s see where ls lives:

~ $ which ls
/bin/ls

That means that there is an actual executable file at in the /bin directory named ls that provides the functionality that we’ve seen for ls. That doesn’t entirely answer our question though because we didn’t type /bin/ls, we simply typed ls.

This leads us to the “PATH”. The PATH is an environment variable that tells your shell which directories to look for to find commands. Let’s see what my PATH looks like using echo.

~ $ echo $PATH
/Users/explorer/.gem/ruby/2.3.1/bin:/Users/explorer/.rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/bin:/Users/explorer/.rubies/ruby-2.3.1/bin:/Users/explorer/bin:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/share/dotnet

Notice: that we had to use a $ when we referenced the variable name. That’s how you access the value of a variable in bash, otherwise it’s just a string “PATH”.

My path is pretty long because it includes a lot of ruby related directories, but we can still break it down. If we take all of the ruby related paths out this is what we’re left with:

/Users/explorer/bin:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/share/dotnet

When we type ls the shell will attempt to find an executable in /Users/explorer/bin. If no executable is found there it will move onto /usr/local/bin, so on and so forth until it either finds an executable or it will exit with an error like this (trying use the obj tool):

~ $ pbj
-bash: pbj: command not found

If you ever see that error you know that what you typed isn’t in your $PATH. This can either be because the file doesn’t exist or isn’t installed, or because you had a typo (pretty common).

Learning More

Almost every time we’re typing into our command line we’re running some program on our system. Most of these tools give us a way to learn more about them through either a --help flag or by giving us a “man page”. If you want to learn more about a command I would suggest first using the man tool like this:

~ $ man pwd

This will open up a scrollable “page” that you can move down by hitting or holding your j key, move up with k, or quit by hitting the q key.

That doesn’t also work, and when it doesn’t then it’s a safe bet to try using --help. Not all tools respond to this, but if they don’t they’ll probably tell you what you could have typed to make the tool work. cd is a good example of this:

~ $ cd --help
cd: usage: cd [-L|-P] [dir]

Other tools will give you “man page” style information without opening in a page so you can scroll through your terminal how you normally would (docker is a good example of this).

Recap

I might be a little too enthusiastic about the shell, but I use it every day and the more that I learn to do from my prompt the better I seem to be at my job. This tutorial was meant to demystify the command line a little and give you a means to learn more on your own. I’ll dig deeper in a later tutorial to show how we can customize our shell experience and some of my favorite command line utilities to use.