Using the Shell

This page is a summary of some things you should know when working with servers via their shell.

1 Servers don’t support GUIs

There are many exceptions to this, but graphical user interfaces require a significant install code base and many servers chose not to install any of that.

2 Servers run Linux

There are a few exceptions to this: some companies that chose to depend entirely on one proprietary operating system provider and some chose to use less-common open systems like Irix or FreeBSD, but Linux has the lions share of the server market.

3 Linux logs you in to a shell

Shells are the programs you interact with when working on the command line. They expect you to provide strings to them, most of which run a process. You commonly interact with the shell through a GUI program called a terminal emulator.

The most common way to get access to a server shell is:

  1. Open a terminal emulator on your computer: cmd.exe on Windows, Terminal.app on MacOS, the terminal window in VS Code, or any other terminal emulator you prefer. It will initially connect to some local shell program on your computer.

  2. Start the ssh process, which connects to the server and opens a shell there.

  3. Send commands to the server’s shell.

4 Shells have their own language

Most Linux shells1 This page only discusses things common to all shells that are compatible with the POSIX standard definition of sh. You’ll probably end up in a much fancier shell like bash or zsh with a wide range of extra features, but those extra features are beyond the scope of this page. are Turing-complete programming languages in their own right. They support variables, functions, conditionals, and loops. They typically have only one data type: string; but some also support arrays.

Variables are accessed by preceding them with $, like $var. Variables as assigned with =, which must not have spaces around it, like var="new value".

Shells are optimized for running other programs. If you do any significant work in a shell script, you’re not using it as intended.

5 Shells are all about stdout, stderr, and stdin

If I just run a process, like ls, it’s stdout and stderr display to my terminal emulator and its stdin reads from my terminal emulator, which in turn will read from my keyboard.

If I want any one of these to interact with a file instead I can do that with just a few characters:

A more powerful tool is to have one process’s stdout map to another process’s stdin. This is also a single-character addendum:

This stdin-to-stdout chaining is called piping and the sequence of programs so chained is called a pipeline. Many powerful shell operations involve piping.

It is unusual to pipe stderr. When building a tool for shell use, stdout should be used to data another application might find helpful and stderr for informing the user of errors or unexpected behavior.

6 Sometimes stdout is enough

If I enclose something in backticks like `ls /tmp` or in dollar-parentheses like $(ls /tmp), it will be treated like a command to run and it will be replaced by its stdout.

mkdir creates a directory for each of its arguments. seq prints a sequence of integers to its stdout. Thus,

mkdir $(seq 340 343)

is the same as

mkdir 340 341 342 343

and creates four directories: $HOME/340, $HOME/341, $HOME/342, and $HOME/343.

7 Shells use environment variables

There are some global-variable-like values called environment variables. These are even more global than most global variables because they persist when invoking a new application. There are many of these, but four are of particular interest:

8 a vs 'a' vs "a"

Any test you type is treated like a string…

… unless it has spaces, in which case it’s treated as several strings …

… or it has various other meaning-changing characters like $, (, and !.

If you put it in double quotes, spaces don’t make several strings but other characters still have special meaning.

If you put it in single quotes, nothing has special meaning.

Assume I’m logged in as user student1.

9 So many commands!

In addition to a few commands built into the shell itself, like cd, any executable on the $PATH can be used as a command in the shell.

When I log in to a new nothing-installed course VM and run

ls $(echo $PATH | grep -o '[^:]*') | wc -l

it tells me there are around2 This is only approximate because a few of the things it is counting might not be programs 2892 such programs which the shell will understand as commands. I used four of them in that line:

The more commands you know, the more powerful the shell becomes.

10 The most important commands

There are many, many others that are useful, but with just these you can do quite a lot.

There are various games designed to teach you about the shell. Three that I recommend are: