A comprehensive command-line reference for Bash and Zsh, organized by topic with examples and compatibility notes.
BeginnerIntermediateAdvanced
01
Basics & Navigation
Beginner
Core commands for moving around the filesystem and getting help.
Print working directorypwd
Outputs the absolute path of the current working directory.
$ pwd
# Output: /home/user
pwd has two modes: logical (default, follows symlinks as-is) and physical (-P resolves all symlinks). Bash's built-in pwd and /usr/bin/pwd may differ in behavior.
List directory contentsls
Lists files and directories. Add flags for detailed output.
$ ls
$ ls -la # long + hidden files$ ls -lh # human-readable sizes$ ls -lt # sorted by modification time$ ls -R # recursive
-l
Long format (permissions, owner, size, date)
-a
Show hidden files (starting with .)
-h
Human-readable file sizes (1K, 234M)
-t
Sort by modification time, newest first
-r
Reverse sort order
-S
Sort by file size
Change directorycd
Navigate the filesystem. Several shortcuts save keystrokes.
$ cd /var/log # absolute path$ cd Documents # relative path$ cd .. # parent directory$ cd ~ # home directory$ cd - # previous directory
cd - returns to the directory stored in $OLDPWD. This variable is set automatically by the shell on every cd command.
Clear terminalclear
Clears the terminal screen. The keyboard shortcut is faster.
Note:clear sends a terminal escape sequence. Scrollback history remains accessible — it's not deleted. Use reset to fully reinitialize the terminal.
Get helpman / --help
Access documentation for any command.
$ man ls # full manual page$ ls --help # brief help text (GNU tools)$ man -k keyword # search man pages (same as apropos)$ info ls # GNU info system (more detailed)
Not all commands support --help. POSIX-standard utilities often use -h. BSD tools (macOS) may have different flags than GNU/Linux counterparts.
Print to screenecho / printf
echo prints text; printf is more powerful with formatting.
echo behavior varies across shells and implementations. For portable scripts, printf is recommended by POSIX. The -e flag is not POSIX-standard for echo.
02
Files & Directories
Beginner
Creating, copying, moving, and deleting files and directories.
Create empty file / update timestampstouch
Creates an empty file if it doesn't exist, or updates its access/modification timestamps.
$ touch file.txt
$ touch -t 202501011200 file.txt # set specific time$ touch -r ref.txt file.txt # use ref file's time
touch creates the file if it doesn't exist. If it does exist, it updates timestamps to the current time. Both access time (atime) and modification time (mtime) are updated by default.
Create directoriesmkdir
Creates one or more directories. -p creates parent directories as needed.
$ mkdir newdir
$ mkdir -p a/b/c # create nested dirs$ mkdir -m 755 secured # set permissions on creation
Without -p, mkdir will fail if a parent directory doesn't exist. With -p, it silently succeeds even if the directory already exists.
Copy files and directoriescp
Copies files or directories. Use -r for directories.
The -exec action runs a command for each result. The {} is replaced with the filename. The \; terminates the command. Using + instead of \; batches filenames for efficiency.
View file contentcat / less / head / tail
Multiple tools for reading files — choose based on file size and need.
$ cat file.txt # print entire file$ less file.txt # paginated viewer (q to quit)$ head -n 20 file.txt # first 20 lines$ tail -n 20 file.txt # last 20 lines$ tail -f /var/log/syslog # follow new output live
cat concatenates files — the name comes from "concatenate." For large files, use less instead. tail -f follows the file as it grows, useful for log monitoring.
Disk usage and spacedu / df
Check how much disk space is used.
$ df -h # filesystem disk space$ du -sh /var/log # size of a directory$ du -sh * | sort -h # all items, sorted
df reports on mounted filesystems. du walks the directory tree and sums file sizes. -h (human-readable) is available in GNU and BSD versions. The sort -h flag sorts by human-readable size (GNU coreutils).
03
Permissions
Intermediate
Unix file permissions use a three-set model: owner, group, and others.
Change file permissionschmod
Sets read/write/execute permissions using octal notation or symbolic mode.
Octal digits: 4=read, 2=write, 1=execute. Three digits apply to: owner, group, others. 755 = rwxr-xr-x, 644 = rw-r--r--. The execute bit on a directory means "traverse" (enter), not execute a program.
Change file ownershipchown
Changes the owner and/or group of a file or directory.
Regular users can only change the group to one they belong to. Only root can change ownership to another user. On macOS/BSD, chown user.group uses a dot instead of colon (both work on Linux).
Change group ownershipchgrp
Changes the group of a file or directory (shorthand for chown :group).
Read the output of ls -l to understand permission strings.
-rwxr-xr-x 1 user group 4096 Jan 1 file.txt
│└──┴──┴── │ │ │ │ │ │
│ u g o │ owner group size date name
└ type └ links
The first character is the file type: -=regular, d=directory, l=symlink, c=char device, b=block device, p=named pipe, s=socket.
04
Process Management
Intermediate
Viewing, controlling, and signaling running processes.
List running processesps
Snapshot of current processes. Commonly used with aux flags.
$ ps aux # all processes, all users$ ps -ef # full-format listing (POSIX)$ ps aux | grep nginx # find specific process
ps aux is BSD-style syntax (no dash). ps -ef is POSIX/SysV-style (with dash). Both work on Linux. The a flag shows all users' processes, u adds user-oriented format, x includes processes without a terminal.
Interactive process viewertop / htop
Real-time view of running processes, sorted by CPU/memory.
$ top # built-in, press q to quit$ htop # enhanced viewer (may need install)$ top -u username # filter by user
Tip: In top, press P to sort by CPU, M to sort by memory, k to kill a process. htop supports mouse interaction and is far more user-friendly.
Kill a processkill / killall / pkill
Sends signals to processes. The default signal is SIGTERM (15), which allows cleanup.
$ kill 1234 # SIGTERM to PID 1234$ kill -9 1234 # SIGKILL (force, no cleanup)$ killall nginx # kill by process name$ pkill -f "python" # kill by pattern matching full cmd
SIGKILL (9) cannot be caught or ignored by the process — the kernel terminates it immediately. SIGTERM (15) is the polite request that allows graceful shutdown. Always try SIGTERM before SIGKILL.
Job control& / bg / fg / jobs
Run commands in the background and switch between foreground/background.
$ sleep 60 & # run in background$ jobs # list background jobs$ fg %1 # bring job 1 to foreground$ bg %1 # resume stopped job in background# Ctrl+Z to suspend a foreground job
Background jobs (&) are tied to the shell session and will be terminated when the session ends, unless started with nohup or disown. Use disown %1 to detach a job from the shell.
Persistent processesnohup / disown
Keep processes running after the terminal session closes.
$ nohup command & # immune to SIGHUP$ nohup command > out.log & # redirect output$ command & disown # disown from current shell
nohup redirects stdout/stderr to nohup.out by default if not redirected. disown removes the job from the shell's job table so it won't receive SIGHUP when the shell exits.
Resource limitsulimit
View or set per-process resource limits for the current shell session.
$ ulimit -a # show all limits$ ulimit -n 4096 # max open file descriptors$ ulimit -s # show stack size limit
ulimit is a shell built-in, not an external command. Limits apply to the current shell and all child processes. Hard limits can only be raised by root; soft limits can be raised up to the hard limit by any user.
05
Text Processing
Intermediate
Filter, search, transform, and analyze text streams and files.
Search text patternsgrep
Searches for lines matching a pattern. One of the most used Unix tools.
Edit text streams via substitution, deletion, and insertion rules.
$ sed 's/foo/bar/' file.txt # first occurrence per line$ sed 's/foo/bar/g' file.txt # global (all occurrences)$ sed -i 's/foo/bar/g' file.txt # in-place edit$ sed '2,5d' file.txt # delete lines 2–5$ sed -n '10,20p' file.txt # print only lines 10–20
On macOS/BSD, sed -i requires an explicit backup extension: sed -i '' 's/foo/bar/g' file. On GNU/Linux, sed -i works without an extension. This is a common portability pitfall.
Text processing languageawk
A powerful pattern-action language for column-oriented text processing.
$ awk '{print $1}' file.txt # print first field$ awk -F: '{print $1}' /etc/passwd # colon delimiter$ awk 'NR==5' file.txt # print 5th line$ awk '$3 > 100' data.txt # filter by field value$ awk '{sum+=$1} END{print sum}' f # sum a column
awk field separator defaults to whitespace (any combination of spaces/tabs). $0 is the entire line, $1 is the first field, NR is the current line number, NF is the number of fields on the current line.
-c counts bytes, not characters. For multi-byte characters (UTF-8), use -m to count characters. On some systems, -m and -c give the same result for ASCII-only files.
06
I/O Redirection & Pipes
Intermediate
Direct the flow of data between commands, files, and file descriptors.
Standard streamsstdin / stdout / stderr
Every process has three standard file descriptors: stdin (0), stdout (1), stderr (2).
# File descriptors:
# 0 = stdin (keyboard by default)
# 1 = stdout (terminal by default)
# 2 = stderr (terminal by default)$ command > out.txt # redirect stdout$ command >> out.txt # append stdout$ command 2> err.txt # redirect stderr$ command > out.txt 2>&1 # both to same file$ command &> out.txt # Bash shorthand for above
&> and >& are Bash-specific shorthand. In POSIX sh, use command > file 2>&1. Order matters: 2>&1 > file is incorrect — stderr would still go to the terminal.
Pipes|
Connects stdout of one command to stdin of the next. The foundation of Unix philosophy.
Pipe stages run in subshells. Variable assignments inside a pipe are not visible in the parent shell. This is a common source of bugs in scripts. In Bash 4.2+, the lastpipe option changes this behavior.
Here documents<<
Pass multiline input to a command without a file.
$ cat << EOF
Line one
Line two
EOF
$ ssh user@host << 'ENDSSH'
echo "On remote machine"
ENDSSH
Quoting the delimiter (<< 'EOF') prevents variable expansion and command substitution inside the heredoc. Without quotes, $var and $(cmd) are expanded.
Here strings<<<
Pass a single string as stdin to a command. Bash/Zsh specific.
$ grep "foo" <<< "foobar"
$ read -r first last <<< "John Doe"
$ base64 <<< "hello"
Here strings (<<<) are a Bash/Zsh extension, not POSIX. The string is opened as a temporary file and passed as stdin. A newline is appended automatically.
Process substitution<() and >()
Treat the output of a command as if it were a file. Bash/Zsh specific.
Process substitution uses named pipes or /dev/fd/N under the hood. It is not available in POSIX sh or dash. Useful when a command requires a filename argument but you want to use command output.
Tip:/dev/null is a special file that discards all data written to it. Reading from it returns EOF immediately. It's sometimes called the "bit bucket."
07
Scripting
Intermediate
Control flow, functions, and error handling for shell scripts.
Shebang / script setup#!/bin/bash
The first line of a script tells the OS which interpreter to use.
#!/bin/bash
# Strict mode — catch errors early
set -euo pipefail
IFS=$'\n\t'
#!/usr/bin/env bash is more portable than #!/bin/bash as it searches $PATH for bash. set -e exits on error, -u treats unset variables as errors, -o pipefail catches pipe failures.
Conditionalsif / elif / else
Test conditions and branch execution. Use [[ ]] in Bash/Zsh (safer than [ ]).
if [[ -f "$file" ]]; then
echo "File exists"
elif [[ -d "$file" ]]; then
echo "It's a directory"
else
echo "Not found"
fi
# Test flags: -f file, -d dir, -z empty, -n non-empty# -e exists, -r readable, -w writable, -x executable
[[ ]] is a Bash/Zsh keyword (not a command). It supports pattern matching (==), regex (=~), and logical operators (&&, ||) without quoting issues that affect [ ].
Loopsfor / while / until
Iterate over items or repeat while a condition holds.
# C-style for loop
for ((i=0; i<5; i++)); do echo "$i"; done
# Iterate over array
for item in "${array[@]}"; do echo "$item"; done
# While loop
while [[ $count -lt 10 ]]; do
((count++))
done
# Read lines from a file
while IFS= read -r line; do
echo "$line"
done < file.txt
When reading files line by line, IFS= read -r line is the correct idiom: IFS= prevents stripping leading/trailing whitespace, -r prevents backslash interpretation.
Functionsfunction / ()
Define reusable code blocks. Arguments accessed via $1, $2, etc.
Use local to limit variable scope to the function. Without local, variables are global to the script. Functions return exit codes (0–255) via return, not values. Use echo + command substitution to "return" strings.
Exit codes and error handling$? / trap
Every command returns an exit code. 0 = success, non-zero = error.
trap registers signal handlers. Common signals: EXIT (any exit), INT (Ctrl+C), TERM (kill), ERR (with set -e). trap - SIGNAL resets a signal to its default behavior.
Arrays() / []
Bash arrays store ordered lists of values. Zsh arrays are 1-indexed by default.
# Bash arrays (0-indexed)
arr=(one two three)
echo "${arr[0]}" # first element
echo "${arr[@]}" # all elements
echo "${#arr[@]}" # array length
arr+=(four) # append element
unset arr[1] # remove element
In Zsh, arrays are 1-indexed by default. In Bash, arrays are 0-indexed. Setting setopt KSH_ARRAYS in Zsh makes them 0-indexed for compatibility.
08
Variables & Expansion
Intermediate
Variable assignment, parameter expansion, and command substitution.
Always quote variable expansions ("$var"). Unquoted $var undergoes word splitting and glob expansion, which causes bugs when values contain spaces or special characters.
Parameter expansion${var:-default}
Bash/Zsh provide powerful inline variable manipulation without external tools.
${var:-default} # use default if unset/empty
${var:=default} # set and use default if unset/empty
${var:+value} # use value only if var is set
${var:?error msg} # exit with error if unset/empty
${var:0:5} # substring: offset 0, length 5
${var#prefix} # remove shortest prefix match
${var##prefix} # remove longest prefix match
${var%suffix} # remove shortest suffix match
${var%%suffix} # remove longest suffix match
${var/pat/repl} # replace first match
${var//pat/repl} # replace all matches
These expansions are POSIX-standard (except // global replace, which is Bash/Zsh). They are faster than spawning sed or awk for simple string operations.
Command substitution$(cmd)
Capture the output of a command as a string value.
today=$(date +%Y-%m-%d)
files=$(ls -la | wc -l)
echo "Today is $today"
echo "Files: $files"
# Old backtick syntax (avoid — harder to nest)
today=`date`
The modern $() syntax is preferred over backticks. It nests cleanly: $(echo $(date)). Backtick nesting requires escaping: `echo \`date\``.
Arithmetic expansion$((...))
Perform integer arithmetic directly in the shell.
echo $((2 + 3)) # 5
echo $((10 % 3)) # 1 (modulo)
echo $((2 ** 8)) # 256 (exponentiation)
((count++)) # increment without echo
result=$(( (a + b) * c ))
# For floating point, use bc or awk:
echo "scale=2; 10/3" | bc # 3.33
Shell arithmetic only handles integers. $((10/3)) returns 3 (truncated). For floating point, use bc, awk, or python3 -c "print(10/3)".
Environment variablesexport / env
Environment variables are passed to child processes; shell variables are not.
$ export MY_VAR="value" # make available to children$ env # list all environment variables$ printenv HOME # print one variable$ unset MY_VAR # remove variable
$ MY_VAR=val command # set for one command only
Shell variables exist only in the current shell. export marks them for inheritance by child processes. A child process cannot modify the parent shell's environment.
09
Networking
Intermediate
Network diagnostics, file transfer, and remote access tools.
Test connectivityping / traceroute
Test host reachability and trace the network path.
ping uses ICMP ECHO_REQUEST packets. Some hosts block ICMP, so no response doesn't necessarily mean the host is down. On macOS, use traceroute; on Linux, traceroute or mtr for combined ping+trace.
HTTP requestscurl
Transfer data using URLs. Supports HTTP, HTTPS, FTP, and more.
SSH default port is 22. Key-based authentication is strongly recommended over passwords. The ~/.ssh/config file can store connection profiles to avoid typing long commands repeatedly.
scp is being deprecated in favor of sftp and rsync in OpenSSH. rsync uses delta transfer — only changed portions of files are sent, making it far more efficient for large syncs.
Network diagnosticsnetstat / ss / nmap
Inspect network connections, open ports, and routing.
$ ss -tulnp # listening ports (modern)$ netstat -tulnp # same (older systems)$ nmap -sV localhost # scan open ports + services$ ip addr show # network interfaces$ ip route show # routing table
netstat is deprecated on modern Linux in favor of ss (from the iproute2 package). ifconfig is similarly replaced by ip. ss reads directly from kernel structures and is faster.
10
Archives & Compression
Beginner
Create, extract, and inspect compressed archives.
tar archivestar
The standard Unix tool for creating and extracting archives.
# Create$ tar -czf archive.tar.gz dir/ # gzip compressed$ tar -cjf archive.tar.bz2 dir/ # bzip2 compressed$ tar -cJf archive.tar.xz dir/ # xz compressed# Extract$ tar -xzf archive.tar.gz
$ tar -xzf archive.tar.gz -C /path/ # to directory# List contents$ tar -tzf archive.tar.gz
-c
Create archive
-x
Extract archive
-t
List contents
-z
Filter through gzip
-j
Filter through bzip2
-J
Filter through xz
-f
Archive filename
-v
Verbose output
-C dir
Extract to directory
Zip archiveszip / unzip
Create and extract ZIP archives, compatible with Windows.
$ zip archive.zip file1.txt file2.txt
$ zip -r archive.zip directory/
$ unzip archive.zip
$ unzip -l archive.zip # list contents$ unzip archive.zip -d /path/ # extract to directory
ZIP uses its own compression and directory structure. tar with gzip (.tar.gz) generally achieves better compression for multiple files because it compresses the combined stream, not each file individually.
gzip / bzip2 / xzsingle file compression
Compress or decompress individual files (not archives).
Compression trade-offs: gzip (fastest, moderate compression), bzip2 (slower, better compression), xz (slowest, best compression). For most cases, tar -czf (gzip) is the practical choice.
11
Zsh-Specific Features
Intermediate
Zsh extends Bash with powerful autocompletion, globbing, and interactive features.
Extended globbing**/ and qualifiers
Zsh glob patterns are far more powerful than Bash's.
# Recursive glob (default in zsh, needs globstar in bash)
ls **/*.txt # all .txt files recursively
ls **/*(.) # regular files only
ls **/*(/) # directories only
ls **/*(Lk+100) # files over 100KB
ls **/*(mh-1) # modified in last hour
In Bash, ** requires shopt -s globstar. Zsh's ** is enabled by default. Zsh glob qualifiers in parentheses are a Zsh-only feature not available in Bash.
Spelling correctionsetopt CORRECT
Zsh can suggest corrections for mistyped commands.
setopt CORRECT # suggest corrections for commands
setopt CORRECT_ALL # suggest for all words# In ~/.zshrc for permanent setting
Tip: When Zsh suggests a correction, you can accept it with y, reject it with n, or type the correct command manually with e.
Directory navigationAUTO_CD / CDPATH
Type directory names without cd, and navigate history.
setopt AUTO_CD # type dir name to cd
setopt AUTO_PUSHD # push dirs onto stack
setopt PUSHD_IGNORE_DUPS
$ dirs -v # view directory stack$ ~2 # cd to stack entry 2
AUTO_CD is one of Zsh's most-used features. It checks if the typed word is a valid directory and runs cd automatically. This does not work in Bash without an alias or function.
Oh My Zshplugin/theme framework
A popular framework for managing Zsh configuration, themes, and plugins.
# Install Oh My Zsh$ sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# ~/.zshrc configuration
ZSH_THEME="robbyrussell"
plugins=(git docker kubectl zsh-autosuggestions)
The official Oh My Zsh install URL uses the GitHub raw domain. Always verify install scripts before running them. Alternatives include Prezto, Zinit, and Antigen for lighter-weight frameworks.
Zsh completion systemcompinit / zstyle
Zsh's completion system (compsys) is the most powerful of any shell.
# Enable completion in ~/.zshrc
autoload -Uz compinit
compinit
# Styled menus
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
compinit loads and initializes the completion system. Running it without -C rebuilds the completion cache on every shell start. Use compinit -C to skip the security check and rebuild only when needed.
12
Git Essentials
Beginner
Version control fundamentals for everyday development.
Repository setupgit init / clone
Initialize a new repo or clone an existing one.
$ git init # new repo in current dir$ git init project-name # new repo in new dir$ git clone https://github.com/user/repo.git
$ git clone --depth 1 url # shallow clone (no history)
Staging and committingadd / commit
Stage changes and record them in the repository history.
git add . stages all changes in the current directory and subdirectories. git add -A stages all changes including deletions from anywhere in the working tree.
git switch and git restore were introduced in Git 2.23 (August 2019) to split the overloaded git checkout command. switch handles branch changes; restore handles file restoration.
Remote operationsfetch / pull / push
Sync with remote repositories.
$ git fetch origin
$ git pull origin main
$ git pull --rebase origin main
$ git push origin feature/login
$ git push -u origin main # set upstream tracking
Tip:git pull --rebase replays your local commits on top of the fetched upstream, creating a cleaner linear history compared to a merge commit.
History inspectionlog / diff / blame
Explore commit history and file changes.
$ git log --oneline --graph
$ git log -p file.txt # patches for a file$ git diff HEAD~1 # changes since last commit$ git diff main..feature # between branches$ git blame file.txt # who changed each line
Undoing changesrevert / reset / restore
Different tools for different undo scenarios.
# Undo a commit (safe — adds new commit)$ git revert HEAD
# Unstage a file$ git restore --staged file.txt
# Reset to a commit (destructive)$ git reset --soft HEAD~1 # keep changes staged$ git reset --hard HEAD~1 # discard all changes
Warning:git reset --hard permanently discards uncommitted changes. git revert is safer for shared branches because it doesn't rewrite history.
13
Advanced Patterns
Advanced
Power-user techniques for efficient scripting and shell usage.
Brace expansion{a,b,c}
Generate multiple strings from a pattern. Expanded before any other processing.
Brace expansion is a shell feature, not a glob. It runs before filename expansion and doesn't require files to exist. Zero-padding in sequences ({01..10}) is a Bash 4.0+ feature.
xargsxargs
Build and execute commands from standard input — bridge between pipes and commands that don't read stdin.
xargs passes arguments as a batch by default (up to ARG_MAX). Use -n 1 to process one argument at a time. Use -P N for parallel execution with N processes. Use -0 with find -print0 to handle filenames with spaces.
teetee
Write to both stdout and a file simultaneously — like a pipe T-junction.
$ command | tee output.txt
$ command | tee -a output.txt # append$ command | tee file1 file2 # multiple files$ command | tee >(process1) >(process2)
tee reads from stdin and writes to both stdout and files. It's useful for logging while still seeing output. The name comes from the T-shaped pipe fitting in plumbing.
String operations without subshellsparameter expansion
Efficient string manipulation without spawning external processes.
# Extract filename from path
path="/home/user/docs/file.txt"
echo "${path##*/}" # file.txt
echo "${path%/*}" # /home/user/docs
echo "${path%.txt}" # strip extension# Case conversion (Bash 4+)
str="Hello World"
echo "${str,,}" # hello world
echo "${str^^}" # HELLO WORLD
Case conversion with ${var,,} and ${var^^} requires Bash 4.0+. macOS ships with Bash 3.x by default. Install Bash via Homebrew (brew install bash) or use Zsh, which also supports these modifiers.
Named pipes (FIFOs)mkfifo
Create persistent named pipes for inter-process communication.
Use case: Named pipes are useful when process substitution isn't available, or when you need to communicate between processes in separate terminal sessions.
Conditional execution&& and ||
Run commands conditionally based on the exit code of the previous command.
# Run second only if first succeeds
mkdir project && cd project
# Run second only if first fails
ping -c1 host || echo "Host unreachable"
# Chain with grouping
{ command1 && command2; } || fallback
&& uses short-circuit evaluation — the right side only runs if the left side exits 0. || runs the right side only if the left side exits non-zero. These are not boolean operators but flow control based on exit codes.
14
Keyboard Shortcuts
Beginner
Readline shortcuts work in Bash and Zsh (Emacs mode by default).
Cursor movementCtrl + keys
Move the cursor without using arrow keys.
Ctrl+A# beginning of lineCtrl+E# end of lineCtrl+F# forward one characterCtrl+B# backward one characterAlt+F# forward one wordAlt+B# backward one wordCtrl+XX# toggle between start and cursor position
These shortcuts use GNU Readline (Emacs mode). Switch to Vi mode with set -o vi (Bash) or bindkey -v (Zsh). In Vi mode, Esc enters command mode with different keybindings.
Editing shortcutsCtrl + keys
Cut, copy, paste, and modify text on the command line.
Ctrl+K# cut from cursor to end of lineCtrl+U# cut from start of line to cursorCtrl+W# cut previous wordCtrl+Y# paste (yank) last cut textAlt+D# cut next wordCtrl+T# swap current and previous charactersAlt+T# swap current and previous wordsCtrl+_# undo
History navigationCtrl + keys
Search and navigate command history efficiently.
Ctrl+R# reverse incremental searchCtrl+S# forward search (may be blocked by terminal)Ctrl+P# previous command (same as ↑)Ctrl+N# next command (same as ↓)!!# repeat last command!$# last argument of previous command!*# all arguments of previous command
Ctrl+S may be blocked by XON/XOFF flow control. Run stty -ixon (or add it to ~/.bashrc) to enable forward history search. In Zsh, Ctrl+S works by default.
Process controlCtrl + keys
Control the terminal and running processes.
Ctrl+C# send SIGINT (interrupt/kill foreground)Ctrl+Z# send SIGTSTP (suspend foreground job)Ctrl+D# send EOF / logout from shellCtrl+L# clear screen (same as clear)Ctrl+\\# send SIGQUIT (quit with core dump)
Ctrl+C sends SIGINT (signal 2), not SIGTERM or SIGKILL. Programs can catch and handle SIGINT. Ctrl+Z sends SIGTSTP which suspends (not kills) the process — it can be resumed with fg.
15
Tips & Tricks
Intermediate
Practical techniques that improve daily command-line productivity.
History trickshistory / !
The shell history is a powerful tool — learn to exploit it.
$ history # list command history$ history | grep ssh # search history$ !42 # run command #42$ !ssh # run last command starting with ssh$ !!:s/old/new # run last cmd with substitution# HISTSIZE=10000 in ~/.bashrc/.zshrc
Tmux / screenterminal multiplexer
Run multiple terminal sessions within one window, and keep sessions alive when disconnected.
$ tmux # start new session$ tmux new -s work # named session$ tmux attach -t work # re-attach to sessionCtrl+B D# detach (session lives on)Ctrl+B C# create new windowCtrl+B %# vertical split pane
Tmux prefix key is Ctrl+B by default. screen uses Ctrl+A. Both tools persist processes when your SSH connection drops. Tmux is generally preferred for new setups.
Aliasesalias
Create shortcuts for frequently used commands.
# In ~/.bashrc or ~/.zshrc:
alias ll="ls -la"
alias la="ls -A"
alias ..="cd .."
alias ...="cd ../.."
alias gs="git status"
alias python="python3"
$ alias # list all aliases$ unalias ll # remove alias
Aliases are only available in interactive shells by default. To use them in scripts, run shopt -s expand_aliases (Bash) before calling them. Functions are more versatile than aliases for complex operations.
Useful one-linerscombinations
Commonly useful shell one-liners for everyday tasks.
# Find and kill a port's process$ lsof -ti:3000 | xargs kill
# Create a dated backup$ cp file.txt "file.$(date +%Y%m%d).bak"
# Repeat a command every 2 seconds$ watch -n 2 df -h
# Show largest files in current dir$ du -sh * | sort -rh | head -10
16
Special Variables
Intermediate
Built-in variables that the shell automatically sets and maintains.
Positional parameters$0 — $@
Automatic variables set when a script is run or a function is called.
$0 # name of the script / shell
$1, $2 # first, second argument
$@ # all arguments (array — preserves quoting)
$* # all arguments (as single string)
$# # number of arguments
"$@" and "$*" differ when quoted: "$@" expands to separate quoted words (correct for passing arguments), "$*" expands to one single string. Always use "$@" for passing arguments to functions/commands.
Process and status variables$$ — $?
Variables about the current shell process and command status.
$$ # current shell's PID
$! # PID of last background process
$? # exit status of last command (0=success)
$- # current shell option flags
$_ # last argument of previous command
$$ gives the PID of the shell running the script (not a subshell). In subshells ($(...)), use $BASHPID (Bash 4+) to get the actual current PID. $$ always refers to the parent shell.
Shell environment variables$HOME — $PATH
Standard environment variables set by the system or login shell.
$HOME # current user's home directory
$USER # current username
$PATH # colon-separated executable search path
$SHELL # path to current shell binary
$PWD # current working directory
$OLDPWD # previous working directory
$EDITOR # preferred text editor
$HISTFILE # path to history file
$LANG # locale setting
Bash/Zsh specific variables$BASH_VERSION
Variables specific to Bash or Zsh that expose shell internals.
# Bash
$BASH_VERSION # e.g., "5.1.16(1)-release"
$BASH_SOURCE # array of source file paths
$LINENO # current line number in script
$FUNCNAME # array of function call stack# Zsh
$ZSH_VERSION # e.g., "5.9"
$PROMPT # prompt string
$fpath # function search path
$BASH_SOURCE[0] gives the path of the currently executing script, even when sourced. This is useful for scripts that need to find their own location: DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)".