
This lesson covers the shell skills used every day: how commands are built, how quoting changes meaning, how PATH finds programs, and how to get help quickly. Examples assume the Bash shell.
A shell is a program that reads what a user types and runs it. Bash is the default shell on many systems. Check the current shell with echo $SHELL.
Prerequisites
- A Linux system from Day 1 in a VM, in WSL, or on bare metal
- Access to a terminal window
- Ability to update packages with
sudo apt updateon Ubuntu orsudo dnf upgradeon Fedora
Anatomy of a command
Commands usually have four parts.
program -s --long argument1 argument2program: the tool to run, for examplelsorcat- options: short options start with a single dash, long options start with two dashes
- arguments: items the program works on, such as files or directories
Examples:
ls -la # list files with details, show hidden files
mkdir projects && cd projects
cp /etc/hosts ./hosts.backupWhen a file name begins with a dash, stop option parsing with -- to avoid surprises, for example rm -- -weird-name or grep -- "-pattern" file.txt.
Built-in and external commands
Some commands are Bash built-ins. Others are external programs stored on disk. Use type or command -V to check.
type cd # builtin
command -V ls # usually /usr/bin/ls
which ls # path of an external programBuilt-ins provide help with help <name>.
help cd
help aliasExternal programs provide manuals and inline help.
man ls
ls --help | lessQuoting rules that matter
Quoting changes how Bash parses text.
- Unquoted text allows globbing and word splitting; spaces break words; wildcards expand
- Single quotes
'...'keep text exact; nothing inside changes - Double quotes
"..."allow variable expansion and command substitution while protecting spaces - Backslash
\escapes the next character only
Examples:
# unquoted: splits on spaces and expands globs
printf %s\n *
# single quotes: literal text
printf '%s\n' *
# double quotes: expands variables but keeps spaces
name="Majd Banat"
echo "Hello $name"
# escape one character
echo A\ BQuote variables by default: "$var". This avoids bugs when values contain spaces or newlines.
Command substitution
Use $(...) to insert the output of one command into another.
# show kernel version inside a sentence
echo "Kernel: $(uname -r)"
# save the current date in a variable
now=$(date +%F)
echo "Today is $now"
# nested example
echo "User $(id -un) on host $(hostname)"Avoid backticks `...` because they are hard to nest and read.
Globbing and expansions
Bash expands patterns before running the program.
# wildcards
ls *.log
ls file?.txt
# character classes
ls report_[AB].pdf
# brace expansion creates many words quickly
mkdir -p logs/{nginx,app,db}
cp -v config.{example,backup}
# tilde expansion to the home directory
cd ~To search for a literal asterisk or question mark, quote the pattern.
grep "*.log" notes.txtNever run rm -rf * without confirming the current directory. Check with pwd, then run ls first to preview what will be removed. Add -i for interactive prompts when unsure.
PATH and how Bash finds programs
When a program name is typed, Bash searches the directories in the PATH variable from left to right.
echo $PATH | tr ':' '\n'Create a personal ~/bin directory and add it to the front of PATH so custom tools take priority.
mkdir -p "$HOME/bin"
# add once to the end of ~/.bashrc
printf '
# add personal bin to PATH
export PATH="$HOME/bin:$PATH"
' >> "$HOME/.bashrc"
# reload the current shell
source ~/.bashrcCreate a small script and run it from anywhere.
cat > "$HOME/bin/hi" <<'EOF'
#!/usr/bin/env bash
echo "Hi from $(hostname)"
EOF
chmod +x "$HOME/bin/hi"
hiSome systems load ~/.profile for login shells and ~/.bashrc for interactive shells. If PATH changes do not persist after login, add the same export to both files.
Variables and environment
Set a shell variable with name=value. Export it when child processes should see it.
color=blue
export color
# or in one line
export color=blue
printenv | grep -i color || truePersistent settings belong in ~/.bashrc so they load in new terminals.
printf '
# custom color for demo
export COLOR_PREFERENCE="blue"
' >> ~/.bashrc
source ~/.bashrcDo not write name = value. Bash will treat it as a command with three arguments. Use name=value with no spaces.
Aliases and small functions
Aliases shorten common commands and small functions automate simple tasks. Keep them in ~/.bashrc.
cat >> ~/.bashrc <<'EOF'
# helpful aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# function with one argument
mkcd() { mkdir -p "$1" && cd "$1"; }
EOF
source ~/.bashrcTest them.
ll
mkcd ~/playground/day2
pwdBypass an alias with a leading backslash.
\ls -1History and faster editing
History and completion speed up work.
- Up and Down: browse previous commands
- Ctrl R: search history; type a few letters and press Enter to run the match
- Tab: complete commands and paths; press Tab twice to see choices
Add timestamps to history entries.
printf '
HISTTIMEFORMAT="%F %T "
' >> ~/.bashrc
source ~/.bashrc
history | tail -5sudo !! repeats the previous command with sudo. Useful after a permission denied error.
If a program hangs, press Ctrl C to send SIGINT. If it still hangs, close the terminal or use kill from another terminal. Process control is covered later in the series.
Redirection and pipes
Input and output redirection and pipes are core building blocks.
# send output to a file (overwrite or append)
ls -la > listing.txt
ls -la >> listing.txt
# read input from a file
wc -l < listing.txt
# pipe output of one command into another
ps aux | grep ssh | grep -v grepChain commands with && when the second should run only if the first succeeds. Use ; to run commands regardless of success.
mkdir -p ~/playground/day2 && cd ~/playground/day2
curl -s https://example.com | wc -cCommon mistakes and quick fixes
- Quote variables: prefer
"$var" - Avoid editing system files as root unless required; prefer
sudofor single commands - Check the source of a command with
type -a <name>to see aliases and paths - Read error messages; Bash often explains what went wrong
- Use
--to stop option parsing when a file name starts with a dash
Up next: Day 3 - Navigating the Filesystem and FHS
Day 3 focuses on the filesystem and the Linux directory layout. Learn fast navigation techniques and safe delete habits.