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.
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. Kommandozeile or Shell). Almost everywhere you will meet, the shell is bash or the very similar zsh.
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 --installReboot, 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.
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.
macOS — Terminal lives in Applications → Utilities; Spotlight (⌘+Space, type “terminal”) is quicker. macOS is Unix underneath, so the concepts all transfer and most commands work unchanged.
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.
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.
pwd — print working directory — answers it:
pwd/home/user
ls — list — shows what is in the current directory:
lsNothing 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-l— long format: one file per line, with size, date and permissions.-a— all, including hidden files (those whose names start with a dot).-lh— long format with human-readable sizes (4.0Krather than4096).
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.
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.
/ 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.lsis 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
cd — change directory:
cd /tmp
pwd/tmp
Some useful forms:
cd ~
cd ..
cd -cd ~— go home. Plaincdon its own does the same.cd ..— up one level.cd -— back to wherever you just were. Surprisingly handy.
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
lsdata
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 datafirst.txt
second.txt
Copying, renaming and moving:
cp data/first.txt data/copy.txt
mv data/copy.txt data/renamed.txt
ls datafirst.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 datafirst.txt
second.txt
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:
lsfirst,rmsecond. Runlswith the same names you are about to delete. Iflsshows what you expect,rmwill 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
rmargument 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.txtalpha
Here -n takes the value 1, and data/first.txt is the argument.
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.csvgamma,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 --verboseYou 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.
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.txtbeta
That is exactly the same command as head -n 1 data/second.txt. The backslashes are only there so a human can read it.
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 --helpOn 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 headman — manual — 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.txtalpha
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.txtalpha
beta
head shows the first lines, tail the last. Both default to 10.
wc -l data/first.txt1 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.txtSame 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.
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.txtalpha
> 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.txtalpha
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.txtbanana
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.txtbanana
Combining the two ideas — filter, then save:
grep "ap" fruit.txt | sort > apples.txt
cat apples.txtapple
apple
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/*.txtdata/first.txt
data/second.txt
* |
any number of characters, including none |
? |
exactly one character |
[abc] |
any one of the listed characters |
ls data/?econd.txtdata/second.txt
The commonest real use by far is applying one command to a whole set of files:
wc -l data/*.txt1 data/first.txt
1 data/second.txt
2 total
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 $FOOBARhello 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 $HOMEThat 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.
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.