The terminal, shell, and prompt¶
Level 0 · Chapter 2 · ⏱️ ~25 min read · Prerequisites: What is Linux?
This chapter takes apart the thing you type into. You'll learn the difference between a terminal, a shell, a console, and a TTY, how to read the prompt, how every command is built from a command name, options, and arguments, and exactly how bash finds and runs the program you asked for.
Why it matters¶
Alex writes a small shell script called daily_report to pull yesterday's sales numbers. It sits in the current folder. Alex types daily_report and gets:
The file is right there. ls shows it. Alex copies a fix from a forum that says to type $ ./daily_report, pastes it in with the dollar sign, and gets $: command not found. Then a colleague says "just use sudo -i and run it from there". Now the prompt ends in # instead of $, and Alex doesn't notice. Ten minutes later a cleanup command meant for a test folder runs as the all-powerful root user.
None of this is about the script. It is about the shell. The shell only looks for commands in a specific list of folders, and the current folder isn't one of them. The $ in documentation is the prompt, not part of the command. The # at the end of a prompt is a warning light that says "you are root". Once you understand how the shell reads a line and finds a program, every one of these mistakes becomes obvious, and so does the fix.
Concepts¶
Four words people mix up¶
People use "terminal", "shell", "console", and "command line" as if they mean the same thing. They don't, and the difference explains a lot of behaviour.
| Term | What it is | Example on Mint |
|---|---|---|
| Terminal | A device or program that shows text output and sends your keystrokes. It knows nothing about commands | GNOME Terminal window |
| Terminal emulator | A graphical program that pretends to be an old hardware terminal | GNOME Terminal, Xfce Terminal, Terminator, Kitty |
| Shell | A program that reads the commands you type, interprets them, and runs other programs | bash |
| Console | The machine's built-in text screen and keyboard, without any desktop | The text login on Ctrl+Alt+F3 |
| TTY | The kernel's name for a terminal device. Short for "teletypewriter" | /dev/tty3, /dev/pts/0 |
A good analogy: the terminal is the telephone, and the shell is the person on the other end of the line. The phone carries your words back and forth. The person understands them and acts on them. You can swap the phone (use a different terminal emulator) and still talk to the same person (bash), or keep the phone and talk to someone else (zsh or Python).
From teletypes to terminal windows¶
The names come from history. In the 1960s and 70s, people used teletypes: electric typewriters wired to a computer. You typed a line, the computer printed its answer on paper. Later came video terminals like the DEC VT100: a screen and keyboard with no computing power of their own, connected to a big shared computer by a cable.
Unix was built around these devices, and Linux inherited the design. The kernel still has a "terminal" subsystem, and terminal devices are still called TTYs. Today the hardware is gone and programs emulate it:
- A terminal emulator is a window that behaves like a VT100-style terminal. Mint Cinnamon's default is GNOME Terminal.
- A pseudo-terminal (pty) is a pair of virtual devices the kernel creates to connect a terminal emulator to a shell. Each terminal window or tab gets one, named
/dev/pts/0,/dev/pts/1, and so on. "pts" means "pseudo-terminal slave", the shell's end of the pair. - A virtual console is a full-screen text terminal provided directly by the kernel, with no graphics. Linux gives you several, named
/dev/tty1to/dev/tty6and up. On Mint, your graphical desktop itself runs on virtual terminal 7.
flowchart LR
K["Your keyboard"] --> TE["Terminal emulator<br/>(GNOME Terminal)"]
TE <--> PTY["Pseudo-terminal<br/>/dev/pts/0"]
PTY <--> SH["Shell<br/>(bash)"]
SH --> P["Programs it starts<br/>(ls, python3)"]
P --> PTY
When you type ls and press Enter, the terminal emulator sends the characters through the pty to bash. Bash starts ls. ls writes its output to the pty, and the terminal emulator draws it on screen. The terminal never "understands" ls. It just moves text.
Escape hatch: virtual consoles
If the desktop freezes, press Ctrl+Alt+F3 to switch to a text console, log in with your username and password, and investigate from there. Press Ctrl+Alt+F7 to get back to the Mint desktop. On some other distros the desktop lives on Ctrl+Alt+F1 or Ctrl+Alt+F2 instead.
The shell¶
A shell is a program that reads commands, works out what they mean, and runs them. It is called a shell because it is the outer layer around the kernel that users interact with. It is also a full programming language: variables, loops, and functions, which you will use in Level 2.
Every shell runs the same basic loop, called a REPL (read, evaluate, print, loop):
flowchart LR
A["Print prompt"] --> B["Read a line"]
B --> C["Split into words,<br/>expand ~ $VAR *"]
C --> D["Find the command"]
D --> E["Run it, wait"]
E --> F["Store exit status"]
F --> A
Several shells exist:
| Shell | Notes |
|---|---|
bash |
The Bourne Again SHell, from GNU (1989). Default interactive shell on Mint, Ubuntu, Debian, RHEL. This handbook uses it |
sh |
The POSIX standard shell. On Mint, /bin/sh is actually dash, a small, fast shell used to run system scripts |
zsh |
Bash-compatible with extra features. Default on macOS |
fish |
Friendly, with autosuggestions. Not bash-compatible |
Each user account has a login shell, recorded in the file /etc/passwd (covered in Users, groups, and sudo). It is the shell started when you log in or open a terminal. The variable $SHELL holds its path.
Interactive vs non-interactive
When you type commands at a prompt, bash is an interactive shell. When bash runs a script file, it is non-interactive: no prompt, and it skips some setup like your aliases. That's why a command can behave slightly differently in a script than at your prompt.
The prompt¶
The prompt is the text the shell prints when it is ready for your next command. On a fresh Mint install it looks like this:
Each part has a meaning:
| Part | Meaning |
|---|---|
alex |
Your username |
@ |
Just a separator |
mint |
The hostname: this machine's name. Vital when you're SSH'd into five servers |
: |
Separator |
~ |
Your current directory. ~ is shorthand for your home directory, /home/alex |
$ |
You are a normal user. It changes to # when you are root, the all-powerful administrator |
Move to another folder and the directory part changes:
Become root (covered in chapter 6) and the colours, name, and final character change:
Common mistake: copying the prompt
Documentation often writes commands as $ ls -l or # apt update. The $ or # shows the prompt, telling you whether to run it as a normal user or as root. Never type it. If you do, bash tries to run a program named $ and prints $: command not found. This handbook avoids the problem by putting commands in their own blocks without prompts.
PS1: where the prompt comes from¶
The prompt is stored in a shell variable called PS1 ("prompt string 1"). Bash reads it before every prompt and replaces special backslash escapes with live values:
| Escape | Expands to |
|---|---|
\u |
Username |
\h |
Hostname up to the first dot |
\H |
Full hostname |
\w |
Current directory, with your home shown as ~ |
\W |
Only the last part of the current directory |
\$ |
# if you are root, otherwise $ |
\t |
Time, 24-hour HH:MM:SS |
\d |
Date, like Fri Oct 02 |
\n |
Newline |
\! |
History number of this command |
\[ ... \] |
Wraps invisible characters such as colour codes, so bash can measure the prompt's width correctly |
Mint sets PS1 in your personal startup file, ~/.bashrc. With colours, the default is:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
It looks scary but decodes cleanly:
${debian_chroot:+($debian_chroot)}shows a label only when you're inside a special isolated environment called a chroot. Normally empty.\[\033[01;32m\]switches to bold green.\033[starts a terminal colour code,01is bold,32is green.\u@\hprintsalex@mint.\[\033[00m\]resets colours.:is literal.\[\033[01;34m\]\wprints the directory in bold blue.\$prints$(or#) and a space.
You'll customise your prompt permanently in Shell productivity. For now, just know it's a variable, not magic.
Anatomy of a command¶
Every command line follows the same grammar. The shell splits the line into words at spaces, and the words play three roles:
ls -l -h --sort=size /var/log /etc
──── ────── ─────────── ────────────────
command options option with arguments
(short) a value (long)
- The command is the first word: the name of the program, builtin, or alias to run.
- Options (also called flags or switches) change how the command behaves. They start with a dash.
- Arguments (also called operands or parameters) are what the command acts on, usually file names, paths, or text.
Options come in two styles:
| Style | Looks like | Notes |
|---|---|---|
| Short | -l, -a, -h |
One dash, one letter. Quick to type |
| Short, combined | -lah |
Same as -l -a -h. Most programs allow this |
| Short with value | -n 5 or -n5 |
The option needs a value right after it |
| Long | --all, --human-readable |
Two dashes, a full word. Readable, good in scripts |
| Long with value | --sort=size or --sort size |
Short and long forms often do the same thing: ls -a and ls --all are identical. Use short forms when typing and long forms in scripts, where clarity matters more than speed.
A few rules make the rest of Linux predictable:
- Everything is case-sensitive.
ls -r(reverse order) andls -R(recursive) are different options.LSis not a command at all. - Spaces separate words.
ls -lworks;ls-llooks for a command namedls-l. To pass an argument that contains a space, quote it:ls "My Documents". - A lone
--ends the options. Anything after it is an argument, even if it starts with a dash.ls -- -weird-filelists a file literally named-weird-file. - Option order usually doesn't matter for GNU tools.
ls -l /etcandls /etc -lboth work. Other systems (macOS, BusyBox) are stricter, so put options first by habit.
Conventions, not laws
The dash conventions are only conventions. Each program parses its own options. Some old tools use different styles: tar xvf without a dash, find -name with a single dash before a long word, dd if=file. The manual for each command (next-but-one chapter, Getting help) is the final word.
How the shell finds and runs a command¶
When you press Enter, bash does a lot of work before anything runs. Simplified, it goes like this:
flowchart TD
A["Line typed"] --> B["Split into words,<br/>do expansions"]
B --> C{"Command word<br/>contains a / ?"}
C -- yes --> X["Run that exact file"]
C -- no --> D{"Alias?"}
D -- yes --> D2["Replace with alias text"] --> B
D -- no --> E{"Keyword, function,<br/>or builtin?"}
E -- yes --> F["Run inside bash itself"]
E -- no --> G{"Found in a PATH<br/>directory?"}
G -- yes --> X
G -- no --> H["'command not found'<br/>exit status 127"]
Here's what each kind of command is:
- An alias is a nickname you define for a longer command. Mint defines
llasls -alFand makeslsmeanls --color=autoso you get colours. - A keyword (reserved word) is part of bash's grammar, like
if,for, andwhile. - A function is a named block of shell code, which you'll write in Level 2.
- A builtin is a command implemented inside bash itself:
cd,echo,pwd,type,help,history,exit. No separate program runs. - An external command is a separate program file on disk, like
/usr/bin/lsor/usr/bin/python3.
Why some commands must be builtins¶
To run an external command, bash asks the kernel to create a new process (a running instance of a program). It forks, making a copy of itself as a child process, and the child execs, replacing itself with the new program. Bash waits for the child to finish, then prints the next prompt.
sequenceDiagram
participant B as bash
participant K as kernel
participant C as child process
B->>K: fork()
K->>C: copy of bash created
C->>K: exec("/usr/bin/ls")
Note over C: now running ls
C-->>B: exits with status 0
B->>B: print next prompt
Each process has its own working directory (the folder it is "in"). A child can change its own working directory but never its parent's. If cd were an external program, it would change directory inside the child, then exit, and your shell would stay exactly where it was. That's why cd has to be a builtin: it changes bash's own state. The same logic applies to exit, export, and source. Other builtins like echo and pwd exist mainly for speed, and also exist as external programs.
PATH: the list of places to look¶
For external commands, bash searches the folders listed in the PATH environment variable. PATH is one string with folder names separated by colons. Bash checks each folder left to right and runs the first match.
A typical Mint PATH:
/home/alex/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
| Folder | What lives there |
|---|---|
/home/alex/.local/bin |
Your personal programs, e.g. tools installed with pip install --user. Added by ~/.profile if the folder exists |
/usr/local/sbin, /usr/local/bin |
Programs installed by hand by the administrator, outside the package manager. Mint also places a few of its own wrappers here |
/usr/sbin, /usr/bin |
Programs from packages. /usr/bin holds most commands you'll use; sbin holds system administration tools |
/sbin, /bin |
Old locations, kept for compatibility. On Mint they are links to /usr/sbin and /usr/bin (see The filesystem layout) |
/usr/games, /usr/local/games |
Games, historically kept apart |
Order matters. Because /usr/local/bin comes before /usr/bin, a program you install by hand to /usr/local/bin wins over a packaged program with the same name. This is how you can run a newer version of a tool without touching the system's copy, and also how a mysterious old version can shadow (hide) the one you expect.
Common mistake: expecting the current folder to be searched
The current directory is not in PATH. Typing daily_report will not run a script sitting in front of you. You must give a path: ./daily_report. The . means "this directory", and the / tells bash "this is a path, don't search PATH". This is a deliberate security choice: otherwise someone could leave a malicious file named ls in a shared folder and wait for you to cd there.
To speed things up, bash remembers where it found each external command in a hash table. The builtin hash lists those remembered paths. If you install a new version of a program in a different PATH folder and bash keeps running the old one, hash -r makes it forget and search again.
type, which, and command -v¶
Three tools answer the question "what will run if I type this?":
| Tool | Kind | Strength | Weakness |
|---|---|---|---|
type |
bash builtin | Knows about aliases, keywords, functions, builtins, and PATH. Always tells the truth for your shell | bash-specific |
which |
external program | Simple, prints the path of the external file | Can't see aliases, functions, or builtins, because it isn't bash |
command -v |
bash builtin, POSIX standard | Short output, ideal in scripts to test if a command exists | Less descriptive |
Prefer type when you're investigating. Use command -v in scripts. Use which only when you specifically want the file path.
Exit status¶
Every command, when it finishes, hands back a small number to the shell: its exit status (also called exit code or return code). It's how programs report success or failure without printing anything.
- 0 means success.
- Anything from 1 to 255 means some kind of failure. Each program decides what its non-zero codes mean.
The special variable $? holds the exit status of the last command. Common values:
| Code | Usual meaning |
|---|---|
| 0 | Success |
| 1 | General failure (e.g. grep found no match, cd to a missing folder) |
| 2 | Misuse: bad option or missing file (e.g. ls on a missing path) |
| 126 | Found the file but it isn't executable (permission problem) |
| 127 | Command not found |
| 130 | Stopped with Ctrl+C (128 + signal number 2) |
Exit status is the foundation of scripting. cmd1 && cmd2 runs cmd2 only if cmd1 succeeded. cmd1 || cmd2 runs cmd2 only if cmd1 failed. Every if statement in bash is really a test of an exit status. You'll use this heavily in Error handling.
Success is zero, which feels backwards
In most programming languages 0 means false. In the shell, 0 means success, because there is one way to succeed and many ways to fail, and the non-zero number tells you which.
Commands and examples¶
Open a terminal¶
On Mint, any of these open GNOME Terminal:
- Press Ctrl+Alt+T.
- Click the terminal icon in the panel.
- Open the menu and search for "Terminal".
Useful keys inside the terminal:
| Keys | What they do |
|---|---|
| Ctrl+Shift+C / Ctrl+Shift+V | Copy and paste. Plain Ctrl+C does something else (below) |
| Ctrl+C | Interrupt: stop the running command |
| Ctrl+D | End of input. At an empty prompt, it closes the shell |
| Ctrl+L | Clear the screen |
| Ctrl+Shift+T | New tab |
Ctrl with + or - |
Bigger or smaller text |
Common mistake: frozen terminal
Pressing Ctrl+S (a reflex from "save" in other apps) pauses terminal output, so it looks frozen. Press Ctrl+Q to resume. This flow-control feature dates from the teletype era.
Which terminal and shell am I in?¶
tty prints the terminal device connected to your shell:
/dev/pts/0 means a pseudo-terminal, so you're in a terminal emulator window or an SSH session. A second tab would show /dev/pts/1. If you switch to a text console with Ctrl+Alt+F3 and log in, tty prints /dev/tty3.
Your login shell:
The shell actually running right now (which could differ, e.g. if you started zsh by hand):
$0 holds the name of the running program. In an interactive bash it's bash. If it shows -bash with a leading dash, it's a login shell, such as on a text console or over SSH.
ps lists processes. $$ is the shell's own process ID, so this shows the shell process itself:
PIDis the process ID, a number the kernel assigns to every process.TTYis the terminal it's attached to:pts/0, matchingttyabove.TIMEis CPU time used so far.CMDis the program:bash.
Read and change your prompt¶
Print the current value of PS1. The double quotes keep the backslashes intact:
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$
The extra part at the front, \[\e]0;\u@\h: \w\a\], sets the terminal window's title to alex@mint: ~. Mint's ~/.bashrc adds it for terminal emulators.
Now change the prompt for this shell only. Single quotes stop the shell from interpreting anything while you assign:
The prompt instantly becomes:
Try a two-line prompt, handy when paths get long:
The change lives only in this shell's memory. Close the terminal (or type exit) and open a new one, and the default returns. Nothing was saved.
Commands, options, and arguments in practice¶
All of these are the same command with options written differently:
An option that takes a value. head prints the first lines of a file; -n says how many:
All three print:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
Case matters:
There is a program called ls but nothing called LS. Now try a command that isn't installed but exists as a package:
That friendly message comes from Ubuntu's command-not-found helper, which Mint includes. It checks a database of package contents and tells you which package provides the missing name. On a minimal server or container, you'd see only bash: sl: command not found. (sl is a joke program that draws a steam locomotive when you mistype ls.)
Ask bash what a name means with type¶
cd is a shell builtin
ls is aliased to `ls --color=auto'
ll is aliased to `ls -alF'
pwd is a shell builtin
if is a shell keyword
python3 is /usr/bin/python3
Each line tells you which branch of the flowchart bash would take. ls is an alias that adds colour, which then runs the real program.
type -a shows every match, in priority order:
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls
ls is /bin/ls
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo
echo exists as both a builtin and a program. The builtin wins because builtins are checked before PATH. /usr/bin/ls and /bin/ls are the same file reached two ways, because /bin is a link to /usr/bin.
type -t prints just the kind, one word, which is useful in scripts:
Compare with which and command -v¶
which ls prints the file it found. which cd prints nothing and fails with status 1, because which is an external program that only searches PATH, and there is no cd file there. which also ignored the ls alias. That's why type is the better investigation tool.
command -v knows about builtins, prints nothing for missing commands, and returns a non-zero status. In a script you'll write things like command -v jq || echo "please install jq".
Look at PATH¶
$PATH is one long colon-separated line. The tr command translates characters; here it turns each : into a newline so you get one folder per line:
/home/alex/.local/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
Count how many programs live in the main folder:
Every one of those is a command you could type.
Run a program that isn't in PATH¶
Make a scratch folder and a tiny script so you can see PATH in action. Don't worry about the details of printf and chmod yet; they're covered in Level 1.
mkdir -p ~/scratch/path-demo
cd ~/scratch/path-demo
printf '#!/bin/bash\necho "report generated"\n' > daily_report
chmod +x daily_report
Now try to run it three ways:
Bash searched every PATH folder and didn't find it. The current folder isn't in PATH.
The / makes it a path, so bash skips the PATH search and runs that exact file.
A full path works from anywhere.
What if the file isn't marked as executable? Remove the permission and try again:
Status 126: found, but not allowed to execute. You'll understand why in Permissions.
Check exit statuses¶
true and false are tiny programs that do nothing except succeed or fail:
A real failure:
ls documents its codes: 0 for OK, 1 for minor problems, 2 for serious trouble such as a missing command-line argument.
Notice that $? is overwritten by every command, including echo. Read it immediately:
The second echo reports the status of the first echo, which succeeded.
Run something long and interrupt it. sleep 100 waits 100 seconds; press Ctrl+C after a moment:
130 means "killed by signal 2", the interrupt signal sent by Ctrl+C. Signals are covered in Processes and signals.
Chain commands based on success with && and ||:
Exercises¶
Exercise 1: Where am I typing? (easy)¶
Open two terminal tabs. In each, find the TTY device, the login shell, and the shell process ID. Then press Ctrl+Alt+F3, log in at the text console, and run tty there. Return with Ctrl+Alt+F7 and type exit at the console first if you want to log out of it (you can switch back with Ctrl+Alt+F3).
Solution
In each tab:
The second tab shows /dev/pts/1 and a different PID. Each tab has its own pseudo-terminal and its own separate bash process. They don't share a current directory, and each keeps its own command history in memory until it exits.
On the text console, tty shows /dev/tty3, a virtual console provided directly by the kernel, and echo $0 shows -bash, a login shell. To log out of the console, switch back with Ctrl+Alt+F3 and type exit.
Exercise 2: Dissect five command lines (easy)¶
For each line, name the command, the options (and their values), and the arguments. Don't run them; just read.
ls -lt /var/loghead -n 20 sales.csvtail --lines=50 -f /var/log/syslogcp -r data/raw backup/grep -i -- -error app.log
Solution
| Line | Command | Options | Arguments |
|---|---|---|---|
| 1 | ls |
-l, -t (combined as -lt) |
/var/log |
| 2 | head |
-n with value 20 |
sales.csv |
| 3 | tail |
--lines with value 50, -f |
/var/log/syslog |
| 4 | cp |
-r |
data/raw, backup/ |
| 5 | grep |
-i; then -- ends options |
-error (the search text), app.log |
Line 5 is the tricky one. Without --, grep would try to read -error as options -e rror. The -- makes everything after it an argument.
Exercise 3: Builtin, alias, keyword, or file? (medium)¶
Predict what kind each of these is, then check with type: cd, echo, ls, ll, time, printf, which, help, history, python3, for. For any that exist in more than one form, which one wins and why?
Solution
cd is a shell builtin
echo is a shell builtin
ls is aliased to `ls --color=auto'
ll is aliased to `ls -alF'
time is a shell keyword
printf is a shell builtin
which is /usr/bin/which
help is a shell builtin
history is a shell builtin
python3 is /usr/bin/python3
for is a shell keyword
Then check duplicates:
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo
printf is a shell builtin
printf is /usr/bin/printf
printf is /bin/printf
time is a shell keyword
time is /usr/bin/time
time is /bin/time
echo, printf, and time all exist in two forms. The bash version wins because bash checks aliases, keywords, functions, and builtins before it searches PATH. time is a keyword (not just a builtin) so it can time a whole pipeline of commands. The separate /usr/bin/time program has different options and output, and you'd have to type its full path to use it. which is an ordinary program, which explains why it can't see aliases or builtins.
Exercise 4: Make your own command (medium)¶
Using the daily_report script from the examples, make it runnable by typing just daily_report, without moving the file, for this terminal session only. Then prove that a new terminal tab doesn't have the change.
Solution
Make sure it's executable, then prepend its folder to PATH for this shell:
cd ~/scratch/path-demo
chmod +x daily_report
PATH="$HOME/scratch/path-demo:$PATH"
daily_report
type daily_report
PATH="$HOME/scratch/path-demo:$PATH" builds a new value: your folder, a colon, then the old PATH. Putting it first means it is searched first. In a new tab, daily_report gives command not found again, because variables you set at the prompt live only in that shell's memory.
The proper permanent home for personal scripts is ~/.local/bin. Mint's ~/.profile adds it to PATH automatically when the folder exists at login. You'll set this up in Level 2.
Exercise 5: A prompt that shows failure (hard)¶
Change your prompt so it shows the exit status of the previous command in square brackets, followed by the usual user@host:dir$. Run true, false, and ls /nope and watch the number change. Explain why the PS1 value must be in single quotes.
Solution
[0] alex@mint:~$ true
[0] alex@mint:~$ false
[1] alex@mint:~$ ls /nope
ls: cannot access '/nope': No such file or directory
[2] alex@mint:~$
Bash re-expands PS1 every time it prints a prompt, including $? and other variables. With single quotes, the literal text $? is stored in PS1, so it's evaluated fresh each time. With double quotes, "[$?] ...", the shell would replace $? once, at the moment you assign it (with the value 0), and the prompt would show [0] forever.
Open a new terminal to get the default prompt back. Level 1 shows how to make prompt changes permanent in ~/.bashrc.
Check yourself¶
-
Explain the difference between a terminal emulator and a shell in one sentence each.
Answer
A terminal emulator is a graphical program that displays text and passes your keystrokes along, like a phone line. A shell is the program that reads those keystrokes as commands, interprets them, and runs programs.
-
What does
/dev/pts/2tell you, compared with/dev/tty2?Answer
/dev/pts/2is a pseudo-terminal, used by a terminal emulator window or an SSH session./dev/tty2is a virtual console provided directly by the kernel, reached with Ctrl+Alt+F2 and running without any graphics. -
Your prompt reads
root@db01:/var/lib/postgresql#. What three facts does it tell you?Answer
You're logged in as
root, on a machine nameddb01, in the directory/var/lib/postgresql. The#confirms you have full administrator power, so be careful. -
In
tar -czf backup.tar.gz /home/alex/data, what are the command, options, and arguments?Answer
Command:
tar. Options:-c(create),-z(gzip),-f(file name follows) combined as-czf, where-ftakes the valuebackup.tar.gz. Argument:/home/alex/data, the folder to archive. -
Why is
cda shell builtin rather than a program in/usr/bin?Answer
External programs run in a child process, and a child can't change its parent's working directory. A
cdprogram would change directory only inside itself and then exit, leaving your shell where it was. As a builtin,cdchanges the shell's own working directory. -
You type
etl_runand getcommand not found, but the file is in your current directory. What are two ways to run it?Answer
Run it with a path, such as
./etl_runor the full path/home/alex/project/etl_run. Or add its folder to PATH, for examplePATH="$PWD:$PATH"for the current session, or move it into~/.local/bin. It also needs execute permission. -
Why might
which python3andtype python3give different answers?Answer
whichis an external program that only searches PATH for files.typeis a bash builtin that also knows about aliases, functions, and builtins. If you have an alias or function namedpython3,typeshows it andwhichdoesn't, and the alias is what actually runs. -
What do exit statuses 0, 1, 126, 127, and 130 typically mean?
Answer
0: success. 1: general failure. 126: the file was found but couldn't be executed (usually missing execute permission). 127: command not found. 130: the command was interrupted with Ctrl+C (128 + signal 2).
Key takeaways¶
- The terminal emulator moves text; the shell (bash) understands commands. TTYs and ptys are the kernel devices that connect them.
- The prompt
alex@mint:~$shows user, host, and directory. A trailing#means root. Never copy$or#from documentation. - Every command line is command, options, arguments, separated by spaces, all case-sensitive.
--ends options. - Bash resolves a name in order: alias, keyword, function, builtin, then PATH. Use
typeto see which one wins. - The current directory is not in PATH. Run local scripts with
./name. - Every command returns an exit status: 0 is success, non-zero is failure. Read it from
$?straight away.
Next¶
You know what you're typing into. Now type something useful: Your first commands.