Part 1 — The command line

Terminal, paths, commands, pipes and wildcards

This is the part that gates a practical. By the end you should be able to open a terminal, say where you are, move around, read a command and its parameters, and send the output of one command into another.

Work through it at a terminal, typing as you go. It takes an evening.

TipEvery command on this page is tested

The bash blocks below are extracted and executed on a clean Linux machine each time this site is built. If a command is shown here, it ran. Your machine may still differ in version or defaults — but the example is not a typo.

Opening a terminal

A terminal (dt. Terminal) is a window that lets you type commands. The program that reads what you type and runs it is the shell (dt. Kommando­zeile or Shell). Almost everywhere you will meet, the shell is bash or the very similar zsh.

ImportantThis material targets Linux

Specifically Ubuntu, which is what you are most likely to sit in front of. Everything here is written and tested for that.

Windows via WSL2 is Linux, so it counts. macOS is close but not the same, and the gaps are noted where they matter — but a Mac is not a platform this material can promise to cover completely.

Linux — search the applications menu for Terminal. On Ubuntu, Ctrl+Alt+T opens one directly. This is the case everything below assumes.

Windows — you need WSL2 (Windows Subsystem for Linux), which runs a real Ubuntu inside Windows. This is not a second-best: much scientific software has no Windows build at all, so the Windows answer to “how do I run this” is genuinely “run Linux”. In PowerShell, as administrator:

wsl --install

Reboot, let it finish setting up, choose a username and password, and from then on start Ubuntu from the Start menu. Everything below then applies to you exactly as written, because you are now running Linux.

WarningDo this before the practical, not during it

The WSL2 install needs a reboot and a download, and occasionally needs virtualisation switched on in the BIOS. That is a fine thing to sort out on a quiet evening and a bad thing to discover in the first ten minutes of a session.

macOSTerminal lives in Applications → Utilities; Spotlight (+Space, type “terminal”) is quicker. macOS is Unix underneath, so the concepts all transfer and most commands work unchanged.

NoteIf you are on a Mac, expect some things to differ

Linux ships the GNU versions of the basic tools; macOS ships the older BSD versions. They agree on the important things and differ at the edges — most visibly, BSD tools generally do not accept --help or long parameter names like --lines, only the short -n form.

This page sticks to the portable form wherever it can, so the examples here run on both. Beyond this page, though, a Mac will occasionally disagree with the instructions — most often with unrecognized option, for exactly this reason, and the fix is usually the short parameter. Not everything can be covered for every platform, and Linux is the one that is.

What you are looking at

You will see something like this.

A terminal window showing the prompt: user1, an at sign, machine, a colon, tilde slash projects, then a dollar sign and a block cursor. A key identifies user1 as your username, machine as the computer you are on, tilde slash projects as where you are right now, and the dollar sign as the shell being ready and waiting.
Figure 1: The prompt, and what each part of it tells you.

That is the prompt: the shell saying it is ready. The part worth watching is where you currently are — it changes as you move around, and it is the cheapest way to answer the question that causes most early confusion.

The $ marks the end of the prompt. You never type it.

On this page, code blocks show the command without a prompt, so you can copy them cleanly. Where output is shown, it is in a separate block.

Where am I?

The single biggest source of early confusion is not knowing where you are. The shell is always sitting in one directory, and most commands act on that directory unless told otherwise.

pwdprint working directory — answers it:

pwd
/home/user

lslist — shows what is in the current directory:

ls

Nothing printed means the directory is empty, which is a real answer, not an error. Silence on success is a Unix habit you will get used to: most commands say nothing when they work and speak up only when something goes wrong.

ls takes parameters that change what it shows:

ls -l
ls -a
ls -lh
  • -llong format: one file per line, with size, date and permissions.
  • -aall, including hidden files (those whose names start with a dot).
  • -lh — long format with human-readable sizes (4.0K rather than 4096).

That last one is two parameters combined into one word, which is normal and worth noticing now: -lh means exactly -l -h.

Reading ls -l output

A long listing packs six things onto one line:

-rw-r--r--  1  user1  staff  1048576  Sep 26 07:08  data.csv
-rw-r--r-- who may read, write and run it. A leading d here means it is a directory.
1 number of links — ignore it for now
user1 the owner
staff the owner’s group
1048576 size in bytes (-h turns this into 1.0M)
Sep 26 07:08 when it was last changed

You do not need to decode permissions today. It is worth knowing the column exists, because Permission denied later on is this column talking.

ImportantEverything is case-sensitive

Data.csv, data.csv and DATA.CSV are three different files, and LS is not a command. Windows does not work this way, so this catches people constantly — and the error you get (No such file or directory) does not mention case, so it reads as “the file is missing” when the file is right there.

The filesystem is one tree

Everything on the machine hangs off a single directory called the root, written /. There are no drive letters — no C:, no D:. A USB stick, a second hard disk and a network share all appear as directories somewhere inside that one tree.

This is the biggest structural difference from Windows, and it is worth looking at before paths will make sense.

A tree diagram. A single root node labelled forward-slash branches into three directories: home, bin and etc. home branches into user1, user2 and user3. user1 branches into Documents and Downloads, plus three files: notes.md, data.csv and myscript.sh. bin contains three programs: ls, mkdir and bash.
Figure 2: The filesystem is a single tree with / at its root. Directories branch; files are leaves. Your own files live under /home/<your name>/.

Two parts of that tree you will meet immediately:

  • /home/<your name>/ — your own files. This is where you start, and where almost all your work belongs. It has a shorthand: ~.
  • /bin, /usr/bin — the programs themselves. ls is a file on disk, and it lives here. That is worth knowing: a command is not magic, it is a program in a directory, which is why “command not found” is a file problem.

Directories and paths

A path (dt. Pfad) is a file or directory’s address — a route through that tree. There are two kinds, and the difference matters more than anything else in this section.

An absolute path starts at the root, /, and is therefore unambiguous from anywhere. Read it against Figure 2 — it is the route from / down to the file:

/home/user1/data.csv

A relative path starts from wherever you currently are. Standing in /home/user1, the same file is just:

data.csv

The second is shorter and is what you will type most of the time. It is also why pwd matters: the same relative path means different things depending on where you are standing.

Three shorthands appear constantly:

. the current directory
.. the directory one level up
~ your home directory

So ~/projects is your projects folder wherever your home happens to be, and ../results is a results folder beside the one you are in.

Moving around

cdchange directory:

cd /tmp
pwd
/tmp

Some useful forms:

cd ~
cd ..
cd -
  • cd ~ — go home. Plain cd on its own does the same.
  • cd .. — up one level.
  • cd - — back to wherever you just were. Surprisingly handy.
TipPress Tab. Always.

Type the first few letters of a name and press Tab. The shell completes it. If nothing happens, press Tab twice to see the options.

This is not a minor convenience. It removes almost every typo, it confirms that what you are about to refer to actually exists, and it is the single habit that most separates people who find the terminal comfortable from people who find it hostile. Use it from your first day, not once you are fluent.

Making, copying and removing

Let us make somewhere to work. These commands build a small directory tree, and everything later on this page uses it.

mkdir -p practice/data
cd practice
ls
data

mkdir makes a directory. The -p parameter means “make parent directories as needed, and do not complain if it already exists” — which is why it can create practice and practice/data in one go.

echo prints its argument back out. On its own that looks pointless —

echo "hello"
hello

— but the next examples send that output straight into a file instead of the screen, which is the fastest way to put text in a file without opening an editor. The redirection section below explains exactly how that works; for now, just read echo "text" > file as “write text into file”.

Now some files to play with:

echo "alpha" > data/first.txt
echo "beta" > data/second.txt
ls data
first.txt
second.txt

Copying, renaming and moving:

cp data/first.txt data/copy.txt
mv data/copy.txt data/renamed.txt
ls data
first.txt
renamed.txt
second.txt

cp copies; mv moves. Renaming is moving — mv from one name to another in the same directory is how you rename a file, and there is no separate command.

Deleting, and why it is different

rm data/renamed.txt
ls data
first.txt
second.txt
ImportantThere is no recycle bin

rm does not move a file to a trash folder. It deletes it. There is no undo, and no dialogue asking whether you are sure.

Two habits worth forming immediately:

  • ls first, rm second. Run ls with the same names you are about to delete. If ls shows what you expect, rm will delete what you expect.
  • Type the name with Tab, not from memory. A name the shell completed for you is guaranteed to exist and be spelled correctly. A name typed from memory is a guess — and a typo in an rm argument is how the wrong thing gets deleted.
  • Be very careful with rm -r, which deletes a directory and everything inside it, recursively. Combined with a wildcard or a stray space it is the classic way to lose a day’s work.

Commands and parameters

Nearly every command follows the same shape:

command  -parameters  arguments
  • the command — the program you are running.
  • parameters, also called flags or options, which change how it behaves.
  • arguments — usually what it should act on, such as a filename.

Parameters come in two styles, and most tools accept both:

style looks like notes
short -l, -h, -n 5 one letter; several can be combined as -lh
long --long, --lines 5 two dashes, a whole word, easier to read later

Short parameters work everywhere. Long ones are a GNU convention, so they work on Linux but often not on macOS — see the note at the top.

Some parameters take a value of their own, some do not:

head -n 1 data/first.txt
alpha

Here -n takes the value 1, and data/first.txt is the argument.

Spaces split arguments — so avoid them in names

This follows directly from what an argument is. The shell splits what you type on whitespace before the command ever sees it, so a space inside a filename is indistinguishable from a space between two arguments.

mkdir -p "lab notebook"
ls
lab notebook

That worked because of the quotes. Without them:

cd lab notebook
bash: cd: lab: No such file or directory

cd receives two arguments, lab and notebook, not one. It looks for a directory literally called lab, which does not exist. Quoting fixes it —

cd "lab notebook"
pwd
cd ..

— but quoting is a workaround you have to remember every time, for every command, forever. The actual fix is upstream of all of it: do not create files or folders with spaces in their names. Use lab_notebook or lab-notebook instead, and the problem never comes up.

This is not academic — it is the single most common way a beginner’s own file breaks the terminal, because graphical file managers and Windows both allow spaces freely, and the terminal is the first place the difference bites.

Tip

Tab-completion protects you here too: complete a space-containing name and the shell quotes or escapes it for you automatically. One more reason it is worth using even when you think you remember the name.

A realistic invocation

One flag on a small command is not what a real call looks like. Here is one that is: sort is an ordinary tool, and this asks it to sort a table by its second column, numerically, largest first.

printf "alpha,12\nbeta,7\ngamma,103\n" > scores.csv
sort -t, -k2 -n -r scores.csv
gamma,103
alpha,12
beta,7

Four parameters, and each does one thing:

-t, the columns are separated by commas
-k2 sort on column 2
-n compare as numbers, not text
-r reverse, so largest first

Drop -n and 103 sorts before 12, because as text it begins with a 1 followed by a 0. That is not a bug — it is the difference between what you asked for and what you meant, and it is exactly the kind of thing parameters exist to pin down.

Serious tools take more of these, and often mix the two styles:

some_tool --input data/ --output results/ -t 4 --verbose

You are not expected to recognise a tool to read that. --input and --output say where things come from and go, -t 4 is almost always “use 4 threads”, and --verbose asks it to say more about what it is doing. Read an unfamiliar command by its parameters — the shape is nearly always the same, whatever the tool does.

TipPrefer long parameters in anything you keep

On Linux, -n 1 and --lines 1 do the same thing. Short ones are quicker to type; long ones are far easier to read six months later, and in a methods section they explain themselves. Type short, save long — and remember that a script written with long parameters will not run on a Mac.

Long commands and the backslash

Real commands get long — long enough that they are written across several lines. A backslash at the very end of a line means “this command continues on the next line”:

head \
  -n 1 \
  data/second.txt
beta

That is exactly the same command as head -n 1 data/second.txt. The backslashes are only there so a human can read it.

WarningThe backslash must be the last character on the line

Not a space, not a comment — the very last character. A trailing space after the backslash breaks the continuation, and the error you get points at the next line, which is a confusing place to start looking.

This matters more than its size suggests: nearly a quarter of the commands in a typical practical are written across multiple lines this way, so a student who cannot read a backslash cannot correctly copy most of the session.

Finding out what a command does

Three things to try, in this order:

head --help

On Linux, most commands accept --help and print a short summary. It is the fastest answer and usually enough. On macOS the base tools are BSD and mostly do not, so there you go straight to man.

man head

manmanual — opens the full documentation. It opens in a pager: scroll with the arrow keys or Space, search by typing /word, and quit with q. Not knowing that q quits is a genuinely common way to get stuck.

For a great many tools, running them with no arguments at all prints usage — though a few will instead sit and wait for input, in which case Ctrl+C gets you out.

Looking at files

You rarely want to print a whole file. These four cover almost everything:

cat data/first.txt
alpha

cat prints the entire file. Fine for something short, a mistake for anything large — printing a million lines to the screen takes a while and tells you nothing.

head -n 2 data/first.txt
tail -n 1 data/second.txt
alpha
beta

head shows the first lines, tail the last. Both default to 10.

wc -l data/first.txt
1 data/first.txt

wc counts words, and -l makes it count lines instead — the common use by a wide margin.

For reading a large file interactively there is less, which opens it in the same pager man uses:

less data/first.txt

Same navigation: arrows and Space to move, /word to search, q to quit.

Editing files: use VS Code

Sooner or later you need to change a file, not just look at it. There are terminal editors — nano is the gentle one, vim the one people make jokes about — and you will meet them eventually, especially on a server where nothing else is available.

For everything else, use Visual Studio Code. This is a strong recommendation, not a neutral menu:

  • It edits files and gives you a terminal in the same window, so you stop alt-tabbing between a file and the command that reads it.
  • It handles the formats you will actually meet — Markdown, JSON, CSV, YAML, Python — with syntax highlighting that makes a malformed file look malformed.
  • Its Remote — WSL extension means Windows users edit Linux files natively, with no copying back and forth. On Windows this is close to essential.
  • It is free, and it is what a great deal of the field uses, so help is easy to find.
WarningDo not edit these files in Word

A word processor will silently add formatting, curly quotes and its own line endings. A file that looks perfect on screen then fails to parse, and the error message will not mention any of that. Use a text editor for text.

Redirection and pipes

This is the part that makes a command line worth learning, and the part that has no equivalent in a graphical program.

Three streams, not one

Every command has three channels, and knowing their names explains several things that otherwise look like bugs:

stream
stdin standard input what goes in — usually what you type, or another command’s output
stdout standard output the actual result
stderr standard error warnings and error messages

The important consequence: > and | move stdout only. Errors and warnings keep going to the screen. So if you redirect a command’s output to a file and still see red text, nothing is broken — that was stderr, which is exactly the design. It means an error can never silently end up inside your results file.

Sending output to a file

By default a command prints its result to the screen. > sends it to a file instead:

head -n 1 data/first.txt > result.txt
cat result.txt
alpha
Warning

> overwrites the target file without warning. >> appends to it instead. If you have ever wondered how someone empties a file by accident, this is how.

echo "second line" >> result.txt
cat result.txt
alpha
second line

Sending output to another command

| — the pipe (dt. Pipe or Rohr) — takes what one command printed and hands it to the next as input, without ever writing a file.

Let us make something worth filtering:

printf "banana\napple\ncherry\napple\n" > fruit.txt
cat fruit.txt
banana
apple
cherry
apple

Now chain some commands together:

sort fruit.txt | uniq -c | sort -rn
      2 apple
      1 cherry
      1 banana

Read it left to right: sort the lines, count how often each one repeats (uniq -c needs its input sorted, which is why sort comes first), then sort that result numerically (-n) in reverse (-r).

grep searches for lines matching a pattern, and is probably the single most useful command here:

grep "an" fruit.txt
banana

Combining the two ideas — filter, then save:

grep "ap" fruit.txt | sort > apples.txt
cat apples.txt
apple
apple
TipThis is the whole idea

Each of these commands does one small thing. None of them knows about the others. The pipe is what turns a handful of simple tools into an answer to a question nobody wrote a program for.

When you meet a long command in a practical, read it as a sentence with | as the punctuation. It almost always says: take this, keep the interesting part, count it, sort it.

Wildcards

A wildcard (dt. Platzhalter) lets one name refer to many files. The shell expands it before the command runs, so the command itself never sees the *.

ls data/*.txt
data/first.txt
data/second.txt
* any number of characters, including none
? exactly one character
[abc] any one of the listed characters
ls data/?econd.txt
data/second.txt

The commonest real use by far is applying one command to a whole set of files:

wc -l data/*.txt
1 data/first.txt
1 data/second.txt
2 total
TipCheck a wildcard with ls before using it with anything destructive

ls and rm expand * identically, so ls tells you exactly what rm would act on — at no risk. This is the same habit as above, and it is the reason it is worth repeating.

Variables, briefly

You do not need to write scripts to meet this — you will read a variable before you ever write one, in someone else’s instructions or in an installer’s output. Enough to recognise it:

FOOBAR="hello world"
echo $FOOBAR
hello world

Assignment is NAME=value, with no space around the =. FOOBAR = "hi" is not an assignment — the shell reads FOOBAR as a command to run, and it almost certainly does not exist. Reading a variable’s value back out needs a $ in front of the name: $FOOBAR, not FOOBAR.

Two you have already been using without a name for them: $HOME is your home directory (it is what ~ is short for), and $PATH is the list of directories the shell searches for a command’s program file — which is why “command not found” is a real error and not just an unhelpful one. Both come already set; you do not need to define them.

echo $HOME

That is the whole scope this page gives it. Writing your own multi-line scripts with variables, loops and conditionals is real programming and belongs in a programming course, not here.

Getting unstuck

A short list that will save you more time than anything else on this page.

situation what to do
A command is running and you want it to stop Ctrl+C
You are stuck in a pager (man, less) q
The prompt has vanished and nothing responds Ctrl+C, then Ctrl+D
You want the command you ran a minute ago arrow, repeatedly
You want one you ran yesterday history, or Ctrl+R and start typing
The screen is a mess clear
You typed a long command and want to fix the start Ctrl+A jumps to the beginning
You are not sure a name is spelled right Do not guess — press Tab

Reading an error message

Error messages look unfriendly and are usually saying something simple. The three you will meet first:

bash: sortt: command not found

The shell does not know that program. Usually a typo; sometimes a tool that is not installed yet, which is what Part 2 is about.

ls: cannot access 'dta': No such file or directory

The path is wrong. Check pwd, then ls to see what is actually there. Almost always this means you are not where you think you are.

bash: result.txt: Permission denied

You are not allowed to do that here. Common when you have wandered somewhere outside your home directory.

TipRead the last line first

When something fails and prints twenty lines, the useful one is usually the last, or the first — rarely the middle. And a command that prints a warning has not necessarily failed: warnings and errors are different, and plenty of tools warn every single time they run.

What you should be able to do now

Check yourself against this list. If you can do all of it, you have what a first practical assumes.

Nothing in that list is about memorising commands. You will look those up forever, and so does everyone else. It is about knowing what is possible, and what to search for.

Where to go next

Part 2 — Installing and managing tools is how you get the tools a practical asks for, and how you keep one project’s tools from breaking another’s.

Part 3 — Git and GitHub is how you keep your work, share it, and get it back after you break something.

Part 4 — Files you will meet covers Markdown, JSON and tabular data, plus the two invisible things that make text files misbehave.