Command Line Fundamentals — Pro Engineering for Recent Grads

Published on 2018-08-17

This is the first post in a series of guides for recent graduates new to the field of software engineering. Oftentimes, inexperienced engineers have misconceptions or are given poor guidance on what to focus on for their ongoing education and growth.

There is a common discomfort and hesitancy with the terminal in both CompSci and bootcamp graduates. Many newcomers adopt other people's dotfiles and configurations (typically belonging to whoever is onboarding them) without an understanding of how those personal setups deviate from the operating system's defaults. Most new engineers will just parrot commands given to them, and it's not uncommon for their engineering mentor to read a command for them to type character-by-character ("el es space dash /eɪ/"). Syntax errors are frequent, and if code is improperly copy-pasted the engineer is unable to parse out where that error occurred. The shell is not a hospitable place for newcomers, but this is one of the areas that you should pay special focus on as a new engineer. 

I don’t want to write a whole tutorial on the command line and shell scripting; you can find those on your own. Hopefully your prior education has equipped you with guidance about how and where to look for help (when in doubt just Google everything — the best engineers do it). This assumes you’ve been exposed to the command-line at a high level, but now’s the time to go a bit deeper.

I’m going to focus on a few areas: terminology, file descriptors and redirection, and how to get help for the command-line on the command-line. The first place to start is to understand some of the terminology I've used here: the shell and the terminal

The terminal is a program that runs on your computer, and even though this is how you use the command-line, this program is still a graphical interface: it's a terminal emulator. It has its own set of preferences for things like setting up colors and keyboard shortcuts. Back in the day, computers used to be just terminals and nothing else, and so there's all kinds of quirks in making a modern computer behave like an old-school terminal while providing modern conveniences (like, for instance, scrolling).  

The shell is the programming environment that your terminal runs. I say a "programming environment", because you're actually inside of an interpreter of a programming language — similar to a REPL that you might have encountered in your education (e.g. Pry in Ruby, the console in web developer tools, Dr Racket, etc.).  The language here is almost always some derivative of the Bourne shell, likely Bash or ZSH. You can find out what shell you're using with the command: echo $0

Unpacking that last command, `echo` is a command that writes arguments to standard output, which I'll talk about in just a second. Whenever you see the dollar sign in the shell, this means you are evaluating a thing, typically a variable. `$0` is a variable that contains the name of the current process. Once you start to think about the code you type in the command line as a programming language unto itself, you'll understand why syntax is so important. Shell has a much more finicky syntax than some of the languages you've been exposed to, so it pays to make sure you pay attention to these quirks when running commands.

The reason to draw a clear distinction between the terminal and the shell won’t be immediately obvious, but it will start to make more sense as you encounter oddities in the display of something, or when you start to use tools like screen and tmux.

I mentioned "standard output" above; that's another vital concept when working in the command line: file descriptors and redirection. Simplistically, every program that runs on your computer is set up with three things: standard input, output, and error. When you type a command in the shell and hit <enter>, that program could do a bunch of stuff. If text appears, that text was likely written to standard output which, by default, is displayed in your terminal. If you open up your terminal and type `rails server` in a Rails application (which is maybe something you did a lot in a bootcamp), the program will start running and start spitting out information back to your terminal. This is the program writing to standard output. You've probably done this inadvertently by writing `puts` or `println` over and over in your program (which all good programmers do). Understanding how programs read from input and write to output on the command line is fundamental, so dive into this as an area for further research and learning. As an exercise, learn how to write something into standard error, redirect that into standard out, and finally write that to a file, like /dev/null.

The final thing to touch on here is how you can use the command line to learn more about the command line. Every time you encounter a command, do this sequence of commands (using `echo` from above as an example):

which echo — Locates where the program is.

echo --help OR echo -h — Most programs are set up to have either "--help" or "-h" as options to get more information about the program.

man echo — Read the manual for the program. 

Get in a habit of doing these steps for every command you encounter when following instructions. 

When you're looking at a manual with `man`, you'll be in your shell's pager — use "j" and "k" to move up and down, and "q" to quit. Start with two commands I just wrote about: `man which` and `man man`. Call `man $PAGER` — which you now know is evaluating a variable called PAGER that is set by your shell. I've been using the terms "command" and "program" interchangeably, but `man command` might be a good place to start to help differentiate those terms.

Prioritize learning the command line early in your career, and it will be immediately beneficial.

From here onward, posts in this series will be for subscribers only. Subscribe to my Drip for free for access.  I'm happy to address questions and help you navigate your command-line explorations in the comments.