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.