Introduction
As a Linux Systems Administrator & DevOps Engineer, I've seen firsthand how mastering terminal commands can streamline workflows and reduce manual effort. The macOS Terminal gives you direct access to powerful tools for file management, process control, text processing, and automation.
This guide is practical and task-focused. Examples target the default macOS shell (zsh on macOS 10.15 Catalina and later) and are POSIX-compatible so they will also work in bash for typical file and process operations.
What you'll learn:
- Core file and process commands (ls, cp, mv, rm, ps, top, kill).
- Text-processing tools and pipelines using grep, awk, sed, and find.
- Basic shell scripting best practices (shebang, error handling, traps).
- Security and troubleshooting tips for safe command-line use.
Work through examples on a non-production system first, and keep scripts in version control as you iterate.
Essential Commands Every Beginner Should Know
Fundamental Terminal Commands
Start with navigation and inspection commands. These are cross-shell and available on macOS out-of-the-box.
ls— list directory contents (use-lfor details,-afor hidden files).cd— change directory;cd ~goes home,cd ..goes up one level.pwd— print working directory.mkdir— create a directory;mkdir -pcreates parents as needed.
Quick example: move into your Projects folder and list hidden files:
cd ~/Documents/Projects
ls -la
Getting Help: man pages and --help
The built-in manual is the definitive reference for most commands. To read the manual page for a command:
man ls
# navigate with arrow keys, PageUp/PageDown
# press q to quit the man pager
Many utilities also support --help for a concise summary, e.g., grep --help. Use command -v <name> or which <name> to find the binary location.
Process Management: ps, top, kill, and monitoring
Common Commands
Process management is essential for diagnosing hung processes or high CPU usage. Use the following built-in commands first:
ps— list processes. Useps auxfor a detailed view of all processes.top— interactive overview of CPU/memory usage; pressqto exit.kill <pid>— send SIGTERM (default) to a process;kill -9 <pid>sends SIGKILL (force).pkill— send signals by process name (use carefully).lsof— list open files, useful to find processes holding files or ports.
Examples and best practices
# Show all processes with user, pid, cpu, mem and command
ps aux | less
# Find processes consuming the most CPU
ps aux --sort=-%cpu | head -n 10
# Use top for a live view (press q to exit)
top -o cpu
# Graceful stop: try SIGTERM first
kill 12345
# If the process won't stop, escalate
kill -9 12345
# Kill processes by name (careful: this kills all matches)
pkill -f 'node server.js'
# Check which process is listening on port 8080
lsof -i :8080
Security and troubleshooting tips: always check the process owner before killing (use ps -o user,pid,cmd -p <pid>), avoid kill -9 unless necessary (it prevents cleanup), and prefer to restart services via their service manager (launchd/systemd) when available.
On macOS specifically, explore launchctl for managing launchd services. For example, launchctl list shows loaded agents and daemons; to stop a running job you can use launchctl stop <service_label>. Use these tools carefully—modifying system services may require sudo and can affect system stability.
# List loaded launchd jobs
launchctl list
# Stop a launched job by its label (replace <label> with the job name)
launchctl stop <label>
For interactive process browsing use htop (available via Homebrew: brew install htop); on Apple Silicon Homebrew paths are often /opt/homebrew/bin, while Intel machines typically use /usr/local/bin.
File Management in the Terminal: Create, Move, and Delete
Creating Files and Directories
Common commands to create files and directories:
touch filename— create an empty file or update timestamps.mkdir foldername— create a directory;mkdir -p dir/subdirfor nested creation.echo 'text' > file.txt— create a file with initial content (overwrites).
touch myfile.txt
mkdir -p project/scripts
echo "#!/usr/bin/env bash" > project/scripts/run.sh
chmod u+x project/scripts/run.sh
Verify creation with ls -l.
File Operations: cp, mv, rm
Copying Files — cp
Use cp to copy files or directories. For directories use -R (recursive).
# Copy a single file
cp file.txt file.bak
# Copy a directory recursively
cp -R project project-backup
# Preserve attributes (permissions/timestamps) when copying
cp -p file.txt /path/to/backup/
Moving / Renaming — mv
mv moves or renames files and directories.
# Rename a file
mv oldname.txt newname.txt
# Move a file into a directory
mv file.txt ~/Documents/Archive/
Removing Files — rm (WITH SAFETY WARNING)
Warning: rm permanently deletes files. There is no OS-level recyclable trash when you use rm — recovery is difficult. Avoid running recursive deletes as root without verifying paths.
rm file.txt— remove a single file.rm -r foldername— remove directory and contents (prompts may vary).rm -f— force removal (suppress prompts).rm -rf /path/to/dir— recursive + force: dangerous; double-check the path and never run assudounless absolutely necessary.
Safe practice: list files before deleting and consider moving items to a temporary folder first.
# Inspect before delete
ls -la /path/to/target
# Move to a temporary 'trash' folder in your home for safer deletion
mkdir -p ~/.local/trash
mv /path/to/target ~/.local/trash/
For repeated safe deletions consider installing a utility that integrates with the macOS Trash instead of rm, or maintain a small script that moves files to your ~/.local/trash for a grace period before permanent deletion.
File Permissions: chmod
Understanding Permissions
Unix-style permissions have three classes: owner (user), group, others. Each class can have read (r), write (w), execute (x). ls -l shows permissions in the first column (e.g., -rwxr-xr--).
Symbolic & Numeric Modes
Two common ways to use chmod:
- Numeric (octal):
chmod 755 script.shequalsrwxr-xr-x. - Symbolic:
chmod u+x script.shadds execute permission for the user.
# Make a script executable for the owner
chmod u+x ./deploy.sh
# Make file readable/writable by owner, readable by group and others
chmod 644 file.conf
# Common for web executables
chmod 755 /usr/local/bin/mytool
Security tip: avoid setting chmod 777 (gives write to everyone). Instead, adjust ownership with chown if needed (e.g., to assign the correct user/group). For shared directories where multiple users need to create files, consider setting the group and using the setgid bit: chgrp developers /srv/shared && chmod g+s /srv/shared. Also set a sensible umask in your shell config to avoid overly permissive defaults.
Advanced Tips and Tricks: Enhancing Your Terminal Experience
Keyboard Shortcuts & History
Ctrl + R— reverse-i-search command history.!!— repeat last command (useful to re-run withsudo).Tab— auto-complete paths and command names.alias— create shortcuts (persist in~/.zshrcor~/.bashrc).
# Make ll persistent
echo "alias ll='ls -la'" >> ~/.zshrc
source ~/.zshrc
Troubleshooting tip: if a command returns permission denied, check file permissions with ls -l and your $PATH using echo $PATH. For missing commands, install via Homebrew (see https://brew.sh/) or check whether the binary is in /usr/local/bin (Intel) or /opt/homebrew/bin (Apple Silicon).
Use command -v <cmd> to confirm which executable will run. For Homebrew-managed tools, brew doctor helps diagnose common installation/path issues.
Shell Scripting Best Practices
When you start automating tasks, prefer small, well-tested scripts with clear error handling and logging. A few recommended practices:
- Include a canonical shebang:
#!/usr/bin/env bashor#!/usr/bin/env zsh. - Fail fast and handle unset variables:
set -euo pipefail(works in bash;set -o pipefailin some shells). - Define
IFSfor safe splitting and useprintffor logging. - Use
trapto cleanup on errors or interrupts. - Lint scripts with ShellCheck (https://www.shellcheck.net/) before committing.
- Keep scripts small, document expected inputs, and store them in Git for review and rollback.
Example: a small, robust backup script skeleton (make executable with chmod +x backup.sh):
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
trap 'echo "ERROR: script failed at line $LINENO" >&2; exit 1' ERR INT TERM
log() { printf '%s\n' "[$(date +"%Y-%m-%d %H:%M:%S")] $*"; }
main() {
log "Starting backup"
rsync -a --delete /path/to/src/ /path/to/dest/
log "Backup completed"
}
main "$@"
Notes and troubleshooting:
- macOS ships with Bash 3.2 for licensing reasons. If you need Bash 5.x features, install via Homebrew (
brew install bash) and update/etc/shellsif you want it as a login shell. - Use ShellCheck to catch unsafe subshells, quoting issues, and unhandled variables before running scripts in production.
- Test scripts interactively and add a dry-run mode (e.g.,
--dry-run) for destructive operations.
AWK & sed Practical Examples
AWK — Field-based text processing
awk is great for columnar data and small aggregations. Use it inside pipelines for concise transformations.
# Print the first column of a space-separated file
awk '{print $1}' data.txt
# Use colon as delimiter (common for /etc/passwd format)
awk -F: '{print $1, $3}' /etc/passwd
# Sum numbers in the 2nd column
awk '{sum += $2} END {print sum}' metrics.txt
More advanced, real-world examples:
# Find top 5 users by accumulated %CPU from ps output
ps aux | awk 'NR>1{cpu[$1]+=$3} END{for (u in cpu) print cpu[u], u}' | sort -rn | head -n 5
# Count ERROR occurrences per logfile found by find (safe with -print0)
find /var/log -name '*.log' -print0 | xargs -0 awk '/ERROR/ {count[FILENAME]++} END {for (f in count) print count[f], f}'
# Average value in 3rd column (skip header)
awk 'NR>1 {sum += $3; n++} END {if (n) printf "%.2f\n", sum/n}' metrics.csv
sed — Stream editor for find & replace
sed performs non-interactive text transformations. On macOS prefer -E for extended regex, and use -i .bak to get a backup when editing in-place.
# Replace 'foo' with 'bar' and print to stdout
sed 's/foo/bar/g' file.txt
# Edit file in-place on macOS (create a .bak backup first)
sed -E -i .bak 's/OLD_VALUE/NEW_VALUE/g' config.ini
# Print lines 1 to 10
sed -n '1,10p' log.txt
Chained examples demonstrating broader workflows:
# Replace a config value across many files found by find (verify the list first)
find ./configs -name '*.conf' -print0 | xargs -0 sed -E -i .bak 's/(db_host=).*/\1db.example.local/'
# Extract and transform, then deduplicate results
grep -h 'ERROR' *.log | sed -E 's/.*ERROR:\s*//g' | awk '{print tolower($0)}' | sort | uniq -c | sort -rn
Security/troubleshooting: always verify outputs before using -i, keep backups or use version control, and test complex regular expressions on a small sample file.
find: Basic Usage
Common options and examples
# Find files by name (case-sensitive)
find . -type f -name '*.log'
# Find files modified in the last 7 days
find /var/log -type f -mtime -7
# Find files larger than 1 megabyte
find . -type f -size +1M
# Use -print0 with xargs -0 to safely handle filenames with spaces
find . -name '*.log' -print0 | xargs -0 grep -n 'ERROR'
# Use -exec to act on each file (dry-run: list before executing)
find . -type f -name '*.tmp' -print
# Once verified, remove:
find . -type f -name '*.tmp' -exec rm -- {} \;
Notes & best practices:
- Always run a query that prints results first (e.g., without
-exec) to verify targets. - Prefer
-print0+xargs -0for safe handling of spaces and special characters in filenames. - On macOS the default
findis the BSD variant. If you need GNU-specific options, install GNU findutils via Homebrew (which providesgfind). - Use
-lsto get a readable listing fromfindduring verification steps.
Security & troubleshooting:
- Do not run destructive
-execcommands assudountil you confirm the matched set. - When working with system directories, ensure you understand the ownership and permissions of files you affect.
- If a command seems slow, narrow the search path or restrict by
-type,-mtime, or-sizeto reduce I/O.
Embrace Advanced Commands
As you grow comfortable with basics, explore combinations that automate real tasks: piping (|), redirection (>, >>), and process substitution. Commands like grep, find, awk, and sed let you search, locate, and edit content at scale.
Example to find errors across log files and show file:line matches:
find . -name '*.log' -print0 | xargs -0 grep -n 'ERROR'
When troubleshooting, combine tail -f with grep to monitor logs in real-time:
tail -f /var/log/myapp.log | grep --line-buffered 'ERROR'
Advanced tips:
- Prefer line-buffered output (
--line-buffered) for streaming pipelines that feed into grep/sed/awk. - For heavy text-processing workloads, consider using tools written for scale (ripgrep, jq for JSON) installed via Homebrew.
- Document complex one-liners in a script so you can version them and test incrementally.
Conclusion: Your Next Steps in Mastering macOS Terminal
Turn knowledge into habit: replace a few GUI actions with command-line equivalents each week. Start small: create aliases, write tiny scripts (#!/usr/bin/env bash or #!/usr/bin/env zsh), and gradually add complexity. Always keep scripts under version control (Git) and document expected inputs/outputs for reliability.
Use built-in documentation with man <command> and --help. For concise examples, check tldr.sh. For Bash/Unix references, see https://www.gnu.org/. For package management on macOS, Homebrew is the common option (https://brew.sh/).
Key Takeaways
- Master navigation and file commands first:
ls,cd,cp,mv,rm. - Use pipelines to compose small tools: prefer
|andxargs -0for safe filenames. - Adopt safe scripting patterns: use shebangs,
set -euo pipefail, traps, and lint with ShellCheck. - Test destructive commands by listing targets first and prefer moving to a local trash directory before permanent deletion.
- Keep tools and scripts in version control and document their behavior for reproducibility.
Everyday Security Checklist
- Inspect files before destructive commands; prefer moving to a local trash directory first.
- Use
chownand groups rather than broad permissions like777. - Limit use of
sudo; audit commands run with elevated privileges. - Keep configuration and scripts in version control; test edits before in-place replacements.
Frequently Asked Questions
- What are some basic Terminal commands for beginners?
- Start with
pwd,cd,ls,mkdir, andtouch. These let you inspect and manipulate files and directories quickly. - How can I find help for terminal commands?
- Use
man <command>for the manual page, or--help(e.g.,grep --help). For concise, practical examples, tldr.sh provides condensed usage notes.