Bash/Shell Commands Cheatsheet
Every essential command-line tool in one place — file management, text processing, networking, scripting, and more. Bookmark this page and never Google a command again.
File System
| Command | Description |
|---|---|
ls -la | List all files including hidden, with details (permissions, size, date) |
ls -lhS | List files sorted by size, human-readable |
cd ~/projects | Change directory — use ~, -, .., or absolute paths |
pwd | Print the current working directory |
mkdir -p a/b/c | Create nested directories, no error if they exist |
rmdir dir | Remove an empty directory |
rm -rf dir/ | Recursively remove directory and all contents (use with caution) |
rm -i file.txt | Remove file with interactive confirmation prompt |
cp -r src/ dest/ | Copy files or directories recursively |
cp -a src/ dest/ | Archive copy — preserves permissions, symlinks, timestamps |
mv old.txt new.txt | Move or rename files and directories |
touch file.txt | Create an empty file or update its timestamp |
find . -name '*.log' | Find files by name pattern recursively |
find . -type f -mtime -7 | Find files modified in the last 7 days |
find . -size +100M | Find files larger than 100 MB |
du -sh */ | Show disk usage summary per subdirectory, human-readable |
df -h | Show free disk space on all mounted filesystems |
ln -s target link | Create a symbolic link |
stat file.txt | Display detailed file metadata (size, inode, timestamps) |
tree -L 2 | Show directory tree limited to 2 levels deep |
File Content
| Command | Description |
|---|---|
cat file.txt | Print entire file contents to stdout |
cat -n file.txt | Print file with line numbers |
less file.txt | Paginated viewer — navigate with j/k, search with /, quit with q |
more file.txt | Simple forward-only pager (spacebar to scroll) |
head -n 20 file.txt | Print the first 20 lines of a file |
tail -n 50 file.txt | Print the last 50 lines of a file |
tail -f app.log | Follow a file in real time (great for logs) |
grep -rn 'pattern' . | Search recursively with line numbers |
grep -i 'error' log.txt | Case-insensitive search in a file |
grep -v 'debug' log.txt | Invert match — show lines NOT containing pattern |
grep -E 'err|warn' log.txt | Extended regex — match multiple patterns |
sed 's/old/new/g' file | Replace all occurrences of old with new |
sed -i '' 's/old/new/g' f | In-place replacement (macOS syntax) |
sed -n '10,20p' file | Print only lines 10 through 20 |
awk '{print $1, $3}' file | Print the 1st and 3rd whitespace-delimited columns |
awk -F: '{print $1}' /etc/passwd | Use : as field separator, print first field |
wc -l file.txt | Count lines in a file (-w for words, -c for bytes) |
sort file.txt | Sort lines alphabetically (-n for numeric, -r for reverse) |
sort -t, -k2 -n data.csv | Sort CSV by 2nd column numerically |
uniq -c | Deduplicate consecutive lines and show counts |
cut -d',' -f1,3 data.csv | Extract 1st and 3rd comma-delimited fields |
tr 'a-z' 'A-Z' | Translate (transform) lowercase to uppercase |
tr -d '\n' | Delete all newlines from input |
tee output.log | Read stdin, write to both stdout and a file |
Permissions & Ownership
| Command | Description |
|---|---|
chmod 755 script.sh | Owner rwx, group rx, others rx (common for scripts) |
chmod 644 file.txt | Owner rw, group r, others r (common for files) |
chmod +x script.sh | Add execute permission for all users |
chmod -R 750 dir/ | Recursively set permissions on a directory |
chmod u+rw,go-w file | Symbolic: add rw for user, remove write for group/others |
chown user:group file | Change file owner and group |
chown -R user dir/ | Recursively change ownership of a directory |
chgrp staff file.txt | Change group ownership of a file |
umask 022 | Set default permission mask (new files get 644, dirs 755) |
umask | Display current umask value |
ls -la | View permissions as rwxrwxrwx alongside owner and group |
stat -f '%Sp %Su %Sg' file | Show permissions, owner, group (macOS) |
Process Management
| Command | Description |
|---|---|
ps aux | List all running processes with details |
ps aux | grep node | Find processes matching a name |
top | Real-time process monitor (q to quit) |
htop | Interactive process viewer with color and mouse support |
kill PID | Send SIGTERM (graceful stop) to a process by PID |
kill -9 PID | Send SIGKILL (force kill) — use as last resort |
killall node | Kill all processes matching a name |
pkill -f 'python app' | Kill processes matching a full command string |
jobs | List background jobs in the current shell |
bg %1 | Resume stopped job #1 in the background |
fg %1 | Bring background job #1 to the foreground |
nohup ./run.sh & | Run command immune to hangups, persists after logout |
cmd & | Run command in the background |
wait | Wait for all background jobs to finish |
lsof -i :3000 | Find which process is using port 3000 |
xargs -P 4 | Run up to 4 parallel processes from stdin |
Networking
| Command | Description |
|---|---|
curl https://api.example.com | Fetch URL content to stdout |
curl -o file.zip URL | Download file from URL, save with given name |
curl -X POST -d '{...}' URL | Send POST request with data payload |
curl -H 'Auth: token' URL | Send request with custom header |
curl -sS URL | jq . | Fetch JSON silently and pretty-print with jq |
wget -c URL | Download file with resume support on interruption |
wget -r -l 2 URL | Recursively download up to 2 levels deep |
ping -c 4 google.com | Send 4 ICMP echo requests to test connectivity |
ssh user@host | Open secure shell connection to remote server |
ssh -L 8080:localhost:80 host | Local port forwarding (tunnel) |
scp file.txt user@host:~/ | Securely copy file to remote server |
scp -r dir/ user@host:~/ | Securely copy directory recursively |
rsync -avz src/ host:dest/ | Sync files efficiently — only transfers diffs |
rsync --delete src/ dest/ | Sync and delete files in dest not in src |
netstat -tulpn | Show listening ports and associated processes |
ss -tulpn | Modern replacement for netstat — faster, more info |
ip addr show | Display network interfaces and IP addresses |
dig example.com | DNS lookup — query name servers for DNS records |
nslookup example.com | Simple DNS query for IP resolution |
traceroute google.com | Trace the network path to a destination |
Archive & Compression
| Command | Description |
|---|---|
tar -czf archive.tar.gz dir/ | Create gzip-compressed tar archive |
tar -xzf archive.tar.gz | Extract gzip-compressed tar archive |
tar -xzf archive.tar.gz -C dest/ | Extract to a specific directory |
tar -tf archive.tar.gz | List contents of a tar archive without extracting |
tar -cjf archive.tar.bz2 dir/ | Create bzip2-compressed tar archive |
gzip file.txt | Compress file in-place (produces file.txt.gz) |
gunzip file.txt.gz | Decompress gzip file in-place |
gzip -k file.txt | Compress and keep the original file |
zip -r archive.zip dir/ | Create zip archive of a directory |
unzip archive.zip -d dest/ | Extract zip to a specific directory |
unzip -l archive.zip | List contents of a zip archive |
xz file.txt | Compress with xz (high compression ratio) |
xz -d file.txt.xz | Decompress xz file |
zcat file.gz | View contents of gzipped file without extracting |
System Info
| Command | Description |
|---|---|
uname -a | Print all system information (kernel, arch, hostname) |
uname -r | Print kernel release version |
whoami | Print the current username |
id | Print user ID, group ID, and group memberships |
hostname | Print or set the system hostname |
date | Print current date and time |
date +%Y-%m-%d | Print date in YYYY-MM-DD format |
uptime | Show how long the system has been running |
free -h | Display memory usage (total, used, free) human-readable |
lsb_release -a | Print Linux distribution information |
cat /etc/os-release | Display OS name, version, and ID |
env | Print all environment variables |
printenv PATH | Print a specific environment variable |
which node | Show the full path of a command binary |
type ls | Show whether a command is an alias, builtin, or file |
alias ll='ls -la' | Create a shorthand alias for a command |
Text Processing
| Command | Description |
|---|---|
echo 'Hello World' | Print text to stdout |
echo -e '\t indented' | Print with escape sequences (tabs, newlines) |
printf '%-10s %d\n' name 42 | Formatted output with padding and types |
xargs -I {} cmd {} | Build and execute commands from stdin items |
xargs -n 1 echo | Execute command once per input line |
tee >(grep err > errs.log) | Tee into process substitution for filtering |
diff file1 file2 | Show line-by-line differences between two files |
diff -u file1 file2 | Unified diff format (common in patches) |
diff -rq dir1/ dir2/ | Recursively compare directories, report only diffs |
comm file1 file2 | Compare two sorted files line by line (3 columns) |
paste file1 file2 | Merge lines from two files side by side |
paste -sd, file.txt | Join all lines into one line with comma separator |
column -t -s, data.csv | Format CSV into aligned columns |
rev | Reverse each line of input character by character |
nl file.txt | Number all non-empty lines in a file |
expand -t 4 file.txt | Convert tabs to 4 spaces |
Shell Features & Scripting
| Command | Description |
|---|---|
cmd1 | cmd2 | Pipe — send stdout of cmd1 to stdin of cmd2 |
cmd > file.txt | Redirect stdout to file (overwrite) |
cmd >> file.txt | Redirect stdout to file (append) |
cmd < input.txt | Redirect file as stdin to a command |
cmd 2> errors.log | Redirect stderr only to a file |
cmd &> all.log | Redirect both stdout and stderr to a file |
cmd 2>&1 | tee log.txt | Merge stderr into stdout and tee to file |
$(command) | Command substitution — capture output as a string |
VAR=value | Set a shell variable (no spaces around =) |
export VAR=value | Set and export variable to child processes |
$HOME, $USER, $PWD, $? | Common variables — home dir, user, cwd, last exit code |
"$VAR" vs '$VAR' | Double quotes expand variables, single quotes are literal |
if [ -f file ]; then ... fi | Conditional — check if file exists |
[ -d dir ] && echo yes | Short-circuit — run echo only if dir exists |
for f in *.txt; do ... done | Loop over files matching a glob |
while read -r line; do ... done < f | Read a file line by line in a loop |
cmd1 && cmd2 | Run cmd2 only if cmd1 succeeds (exit code 0) |
cmd1 || cmd2 | Run cmd2 only if cmd1 fails (non-zero exit) |
{ cmd1; cmd2; } > out.txt | Group commands and redirect combined output |
history | grep ssh | Search command history for past commands |
!! | Re-run the last command |
sudo !! | Re-run the last command with sudo |
set -euo pipefail | Strict mode — exit on error, unset var, or pipe fail |
#!/usr/bin/env bash | Portable shebang line for Bash scripts |
FAQ
What is the difference between Bash and Shell?
A "shell" is any command-line interpreter (sh, bash, zsh, fish, etc.). Bash (Bourne Again SHell) is the most common shell on Linux and older macOS. macOS now defaults to Zsh, which is largely Bash-compatible. Most commands on this page work in any POSIX-compatible shell.
How do I make a Bash script executable?
Add a shebang line (#!/usr/bin/env bash) as the first line of your script, then run chmod +x script.sh. You can then execute it with ./script.sh. The shebang tells the OS which interpreter to use.
What does set -euo pipefail do and should I use it?
It enables strict mode: -e exits on any error, -u treats unset variables as errors, -o pipefail makes pipes fail if any command in the chain fails. It's strongly recommended at the top of every Bash script to catch bugs early instead of silently continuing after failures.
How can I chain multiple commands together?
Use && to run the next command only if the previous succeeds, || to run only if it fails, ; to run regardless of success, and | (pipe) to feed one command's output into another. For example: mkdir build && cd build && cmake .. runs each step only if the previous one worked.