On this page

The shell is more than a place to type commands — it is a small programming environment. This chapter covers the features that make everyday work productive.

Getting help — man and –help

No one remembers every flag. Every command ships with documentation you can read from the terminal.

man <cmd> opens the manual page for a command:

$ man ls

Inside the man page: press / and type to search, n for the next match, and q to quit. Use Space to scroll down a page at a time.

For a quick summary instead of the full manual, most commands accept --help (or -h):

$ ls --help
$ tar --help

Not every command has a man page or --help (shell built-ins often don’t), but most do. If you are not sure what a command does, apropos <keyword> searches man pages for a topic:

$ apropos compress

To find where a command lives — useful when command not found is confusing you — use which:

$ which ls
/usr/bin/ls

If which prints nothing, the command is either not installed or a shell built-in. type tells you which it is:

$ type cd
cd is a shell builtin
$ type ls
ls is /usr/bin/ls

Pipes — connect commands

A pipe (|) sends the output of one command as input to the next.

$ ls | wc -l
14

This chains unlimited commands:

$ ps aux | grep sshd | head -5

Pipes are the heart of the Unix philosophy: small tools doing one thing, combined on demand.

Redirection — send output to files

> writes a command’s output to a file, overwriting it:

$ echo "content" > file.txt
$ cat file.txt
content

>> appends instead of overwriting:

$ echo "more" >> file.txt
$ cat file.txt
content
more

2> redirects error output, which is otherwise separate from normal output:

$ ls nonexistent 2> errors.txt
$ cat errors.txt
ls: cannot access 'nonexistent': No such file or directory

To discard output entirely, send it to /dev/null:

$ command > /dev/null

To write to a file and still see the output on screen at the same time, use tee:

$ echo "hello" | tee log.txt
hello
$ cat log.txt
hello

Globbing — wildcards

The shell expands *, ? and [] before running a command. * matches any number of characters:

$ echo *.txt
f1.txt f2.txt f3.txt

? matches exactly one character:

$ echo f?.txt
f1.txt f2.txt

Brace expansion {a,b} generates a list:

$ echo {a,b,c}.txt
a.txt b.txt c.txt

Globs work anywhere a path is expected:

$ rm *.log
$ cp *.txt backup/

Environment variables

Variables store values the shell and programs can read. $VAR expands to the value.

$ echo $HOME
/home/user
$ echo $USER
user

Set your own (lasts for this shell session only):

$ MYVAR=hello
$ echo $MYVAR
hello

export makes a variable available to programs you launch:

$ export MYVAR

Common built-in variables: $HOME (home directory), $USER (username), $PATH (where the shell looks for commands), $SHELL (current shell).

history — your command history

The shell remembers everything you type. Press the Up arrow to step back through it, or use history:

$ history
 1234  ls -la
 1235  cd Documents

Search your history interactively: press Ctrl+R and start typing.

alias — command shortcuts

alias creates a short name for a longer command.

$ alias ll="ls -l"
$ ll
total 4
-rw-r--r-- 1 user user 13 Aug  5 10:00 file.txt

List existing aliases:

$ alias
alias ll='ls -l'

Aliases only last for the current session. To keep them, add the line to ~/.bashrc — then open a new terminal (or run source ~/.bashrc).

Running in the background

Appending & to a command runs it in the background — the terminal prompt returns immediately and you can keep typing while it works:

$ sleep 30 &
[1] 1234

jobs lists the background jobs of the current shell:

$ jobs
[1]+  Running                    sleep 30 &

fg brings a job back to the foreground, bg resumes a suspended one. (A job suspended with Ctrl+Z can be resumed in the background with bg.)

If you want a long-running job to survive you logging out, use nohup:

$ nohup ./backup.sh &

nohup ignores the hangup signal sent when a session ends and writes output to nohup.out instead of the terminal. Combined with tmux (below) it is the classic way to leave work running on a remote server.

tmux — terminal multiplexer

tmux runs multiple terminal sessions inside one window and lets you detach and reattach to them. The killer feature: a session keeps running after you disconnect, so you can SSH out and pick up exactly where you left off.

Install it if missing:

$ sudo apt install tmux        # Ubuntu
$ sudo dnf install tmux        # Fedora
$ sudo pacman -S tmux          # Arch

Start a session:

$ tmux new -s mysession

Everything inside tmux uses the prefix key Ctrl+B, followed by another key (the first two rows are shell commands, typed outside tmux like any other command):

Keys Action
Ctrl+B d detach (session keeps running)
tmux attach -t mysession reattach
tmux ls list running sessions
Ctrl+B c new window
Ctrl+B n / Ctrl+B p next / previous window
Ctrl+B % split pane vertically
Ctrl+B " split pane horizontally
Ctrl+B x close the current pane

The workflow over SSH: start a session, do long work, Ctrl+B d to detach, disconnect — and later tmux attach to continue as if you never left.

For the whole picture — panes, zoom, scrollback and a two-line config — the guide tmux — Staying Attached goes deeper.