10/10 --Advanced Terminal Workflows and Troubleshooting
You've learned how to navigate directories, manage files, search through content, control processes, troubleshoot networks, and write shell scripts.
Now it's time to connect all those skills.
Real terminal proficiency isn't about memorizing hundreds of commands. It's about knowing how to combine a few powerful tools to investigate problems, understand your system, and complete complex tasks efficiently.
In this final chapter of Terminal Mastery: Windows, macOS & Linux, we'll explore:
- Advanced command-line workflows
- Systematic troubleshooting techniques
- Environment variables and PATH management
- SSH and remote development
- Logs and diagnostic information
- Package and disk management
- Developer workflow automation
- Terminal productivity and customization
- Practical troubleshooting scenarios
Let's bring everything together.
1. Think in Workflows, Not Individual Commands
A beginner often thinks:
"I need to find a file. Which command should I use?"
An experienced developer thinks:
"I need to locate the file, inspect its contents, identify the relevant information, and possibly modify it."
That's a workflow.
A workflow is a sequence of operations that solves a larger problem.
Consider this example:
You want to find every occurrence of TODO in a project, excluding dependency directories.
Linux and macOS
rg -n "TODO" . \ --glob '!node_modules/**' \ --glob '!dist/**' \ --glob '!vendor/**' Windows PowerShell
Get-ChildItem -Path . -Recurse -File | Where-Object { $_.FullName -notmatch '[\\/](node_modules|dist|vendor)[\\/]' } | Select-String -Pattern "TODO" Both commands solve the same problem, but use different approaches.
The Bash example uses ripgrep, while PowerShell combines file discovery, filtering, and text search.
The important lesson:
Don't just learn commands. Learn how to combine them.
2. Build a Systematic Troubleshooting Process
When something breaks, randomly trying commands usually wastes time.
A better approach is to investigate problems in a consistent order.
Here's a practical troubleshooting framework:
- Reproduce the problem.
- Identify the affected component.
- Check the relevant process or service.
- Inspect logs and error messages.
- Check configuration and environment variables.
- Verify filesystem permissions.
- Test network connectivity if necessary.
- Apply one change at a time.
- Verify that the problem is resolved.
Let's apply this process to a real development scenario.
Scenario: Your development server isn't starting
Suppose you run:
npm run dev But the application fails to start.
Instead of immediately reinstalling dependencies, investigate.
Step 1: Check Node.js and npm
Linux, macOS, PowerShell:
node --version npm --version Step 2: Check whether the expected files exist
Linux and macOS:
ls -la PowerShell:
Get-ChildItem -Force Look for:
package.json node_modules/ src/ Step 3: Inspect the package scripts
npm run This displays the available scripts defined in package.json.
Step 4: Check whether the port is already in use
Linux:
ss -ltnp macOS:
lsof -iTCP -sTCP:LISTEN -P -n Windows PowerShell:
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess Step 5: Identify the process
Linux and macOS:
ps aux | grep node PowerShell:
Get-Process node Step 6: Inspect the error
Don't ignore the actual error message.
It might indicate:
- A missing dependency.
- A syntax error.
- An occupied port.
- A missing environment variable.
- An invalid configuration file.
- A permission problem.
The goal is to identify the cause before changing the system.
3. Understand Environment Variables and PATH
Environment variables are values provided to processes by their execution environment.
They're commonly used for:
- Configuration
- API endpoints
- Runtime settings
- Credentials
- Tool locations
- Application modes
Display environment variables
Bash:
printenv PowerShell:
Get-ChildItem Env: Windows CMD:
set Read a specific variable
Bash:
echo "$HOME" echo "$PATH" PowerShell:
$env:USERPROFILE $env:PATH CMD:
echo %USERPROFILE% echo %PATH% Create an environment variable
Bash:
export APP_ENV="development" PowerShell:
$env:APP_ENV = "development" CMD:
set APP_ENV=development These examples set variables for the current shell session and its child processes.
They don't automatically create permanent system-wide settings.
What is PATH?
PATH is an environment variable containing directories where the operating system looks for executable commands.
For example, when you type:
node Your shell or operating system searches the relevant executable locations.
If Node.js is installed but isn't available as a command, its installation directory might be missing from PATH.
Check where an executable is located:
Linux:
command -v node macOS:
which node PowerShell:
Get-Command node Windows CMD:
where node This is one of the first things to check when a command suddenly stops working.
Inspect your PATH
Bash:
echo "$PATH" | tr ':' '\n' PowerShell:
$env:PATH -split ';' CMD:
echo %PATH% Be careful when modifying PATH. Accidentally replacing its existing value can make other applications unavailable from the command line.
4. SSH: Work with Remote Machines
Developers frequently work with remote servers.
For example:
- Deploying applications.
- Accessing Linux servers.
- Managing cloud infrastructure.
- Running commands on development machines.
- Transferring files between computers.
SSH stands for Secure Shell.
It provides an encrypted connection to a remote machine.
Connect to a server
ssh username@192.168.1.100 If the server uses a non-default SSH port:
ssh -p 7991 username@192.168.1.100 This works from Linux, macOS, and modern Windows systems with an OpenSSH client installed.
Use an SSH key
Generate a key pair:
ssh-keygen -t ed25519 -C "developer@example.com" This creates a private key and a public key.
The private key must remain private.
The public key can be installed on the remote server.
On many Linux systems, you can add your public key with:
ssh-copy-id username@server-address If ssh-copy-id isn't available, you can install the public key manually using the server's authorized-keys mechanism.
Then connect:
ssh username@server-address Use SSH config
Typing a long connection command repeatedly is inconvenient.
Create or edit:
~/.ssh/config Add:
Host dev-server HostName 192.168.1.100 User developer Port 7991 IdentityFile ~/.ssh/id_ed25519 Now connect using:
ssh dev-server This works with OpenSSH clients on Linux, macOS, and Windows.
Copy files using SCP
Upload a file:
scp app.zip username@server-address:/home/username/ Download a file:
scp username@server-address:/home/username/app.log . Copy a directory recursively:
scp -r ./project username@server-address:/home/username/ For more advanced synchronization, rsync is another useful tool on systems where it's available.
Example:
rsync -avz ./project/ username@server-address:/home/username/project/ SSH is an essential tool for developers who work with remote environments.
5. Inspect Logs Like a Professional
Logs are one of the most valuable sources of diagnostic information.
Applications, servers, and operating systems generate logs to record events.
When an application fails, logs can help explain what happened.
Read the last lines of a log
Linux and macOS:
tail -n 50 app.log Windows PowerShell:
Get-Content .\app.log -Tail 50 Follow a log in real time
Linux and macOS:
tail -f app.log PowerShell:
Get-Content .\app.log -Wait This is particularly useful when testing an application while watching its output.
Search for errors
Linux and macOS:
grep -i "error" app.log PowerShell:
Select-String -Path .\app.log -Pattern "error" Combine filtering and following
You can filter a live log stream:
tail -f app.log | grep -i "error" Now you'll see matching error lines as they appear.
Inspect system logs on Linux
Many Linux distributions use systemd and its journal.
View recent system logs:
journalctl -n 100 Follow logs in real time:
journalctl -f Inspect a specific service:
journalctl -u nginx View logs from the current boot:
journalctl -b Not every Linux distribution uses systemd, so these commands may not be available everywhere.
Inspect Windows event logs
PowerShell provides access to Windows event logs:
Get-WinEvent -LogName System -MaxEvents 20 For application events:
Get-WinEvent -LogName Application -MaxEvents 20 You can filter by level:
Get-WinEvent -FilterHashtable @{ LogName = "System" Level = 2 } -MaxEvents 20 Event level 2 represents an error.
Knowing where to look is often half the troubleshooting process.
6. Disk Space and Storage Diagnostics
A full disk can cause unexpected problems:
- Applications fail to write files.
- Package installations stop.
- Databases become unavailable.
- Docker containers fail.
- Build processes crash.
Check available disk space
Linux:
df -h macOS:
df -h PowerShell:
Get-PSDrive -PSProvider FileSystem Windows CMD:
wmic logicaldisk get DeviceID,Size,FreeSpace Note: WMIC is deprecated and may not be installed on newer Windows versions. PowerShell is generally preferable.
Find large directories
Linux:
du -sh * macOS:
du -sh * PowerShell:
Get-ChildItem -Directory | ForEach-Object { $size = ( Get-ChildItem $_.FullName -File -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum ).Sum [PSCustomObject]@{ Directory = $_.Name SizeMB = [math]::Round($size / 1MB, 2) } } | Sort-Object SizeMB -Descending The PowerShell example recursively measures files and can take time on large directories. It may also omit inaccessible files.
Find large files
Linux:
find . -type f -size +100M macOS:
find . -type f -size +100M PowerShell:
Get-ChildItem -File -Recurse | Where-Object { $_.Length -gt 100MB } | Select-Object FullName, Length Check Docker disk usage
If you're a developer using Docker, inspect its storage usage:
docker system df You can inspect containers and images:
docker ps -a docker images Don't blindly run cleanup commands such as:
docker system prune -a They can remove unused images, containers, networks, and build cache. Understand what will be removed before confirming a cleanup operation.
7. Package Managers: Keep Your Tools Updated
Package managers make it easier to install, update, and remove software.
Different operating systems commonly use different package managers.
| Platform | Package manager | Example |
|---|---|---|
| Windows | Winget | winget install Git.Git |
| macOS | Homebrew | brew install git |
| Ubuntu/Debian | APT | sudo apt install git |
| Fedora | DNF | sudo dnf install git |
| Arch Linux | Pacman | sudo pacman -S git |
Update package information and software
Ubuntu/Debian:
sudo apt update sudo apt upgrade Fedora:
sudo dnf upgrade macOS:
brew update brew upgrade Windows:
winget upgrade --all Package managers are not interchangeable.
Always check the package manager available on your system and review what an upgrade will change.
8. Advanced Pipelines: Connect Tools Together
One of the most powerful terminal concepts is the pipeline.
A pipeline sends the output of one command into another command.
Find the most frequently occurring values
Linux and macOS:
sort access.log | uniq -c | sort -nr | head -10 This example:
- Sorts the lines.
- Counts repeated lines.
- Sorts the counts numerically in descending order.
- Displays the first ten results.
It is a simple way to discover repeated log entries.
Find large files and sort them
Linux and macOS:
find . -type f -printf '%s %p\n' | sort -nr | head -10 This particular find format is supported by GNU find, not the default BSD find on macOS.
A more portable macOS alternative is:
find . -type f -exec du -h {} + | sort -hr | head -10 The output and sorting behavior can vary slightly across platforms.
PowerShell pipeline example
PowerShell pipelines pass objects rather than just plain text.
Find the ten largest files:
Get-ChildItem -File -Recurse | Sort-Object Length -Descending | Select-Object -First 10 FullName, Length This is a major PowerShell advantage.
Instead of parsing formatted text, you can directly work with object properties such as:
NameFullNameLengthLastWriteTimeExtension
Understanding the difference between text pipelines and object pipelines helps you write much more reliable scripts.
9. Manage Background Tasks and Long-Running Commands
Not every command finishes immediately.
Build processes, downloads, database operations, and development servers may run for a long time.
Bash: run a process in the background
npm run dev & The & starts the command in the background.
See background jobs:
jobs Bring a job to the foreground:
fg You can also run a process with nohup:
nohup npm run dev > app.log 2>&1 & This allows the process to continue after the terminal session ends in common shell environments.
However, it is not a full service manager. For production services, use an appropriate process manager or operating-system service mechanism.
PowerShell: Start-Process
Start-Process -FilePath "node" -ArgumentList "server.js" Start a process and redirect its output:
Start-Process ` -FilePath "node" ` -ArgumentList "server.js" ` -RedirectStandardOutput "output.log" ` -RedirectStandardError "error.log" Inspect running processes
Bash:
ps aux PowerShell:
Get-Process Stop a process
Bash:
kill 1234 PowerShell:
Stop-Process -Id 1234 Always verify the process ID before stopping a process, especially on shared or production systems.
10. Terminal Productivity: Work Faster Without Memorizing Everything
A professional terminal workflow is not just about powerful commands.
It's also about reducing friction.
1. Use command history
Bash:
history Search interactively in many Bash configurations:
Ctrl + R PowerShell:
Get-History You can also use Ctrl + R in common PSReadLine configurations to search history.
2. Use aliases
Bash:
alias ll='ls -lah' alias gs='git status' PowerShell:
Set-Alias ll Get-ChildItem For a more customized PowerShell alias, define a function:
function gs { git status } Aliases are useful for frequently repeated commands, but don't overuse them.
A script should remain understandable to someone who doesn't know your personal aliases.
3. Use tab completion
Instead of typing an entire directory name, start typing and press:
Tab Most modern shells support some form of completion.
It can help complete:
- File names
- Directory paths
- Commands
- Parameters
- Git branches, with suitable configuration
4. Use terminal multiplexers
On Linux and macOS, tools such as tmux allow you to manage multiple terminal sessions in one window.
Start a session:
tmux Detach from a session:
Ctrl + B, then D List sessions:
tmux ls Reattach:
tmux attach This is especially useful when working with remote servers over SSH.
5. Customize your shell
Popular options include:
- Zsh with Oh My Zsh
- Starship prompt
- PowerShell profiles
- PSReadLine
- Fish shell
A good terminal setup can provide:
- Git branch information
- Command execution duration
- Current directory
- Tool versions
- Useful completions
- Syntax highlighting
Keep customization practical. A beautiful prompt is nice, but a fast and understandable workflow is more important.
11. Practical Troubleshooting Scenarios
Let's test everything with some realistic problems.
Scenario A: Port Already in Use
You start a development server and receive:
Error: listen EADDRINUSE: address already in use This means another process is already listening on the requested port.
Find the process.
Linux:
sudo ss -ltnp | grep ':3000' macOS:
lsof -i :3000 Windows PowerShell:
Get-NetTCPConnection -LocalPort 3000 -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess Find the process name in PowerShell:
Get-Process -Id 1234 If it's safe to stop:
Stop-Process -Id 1234 Or on Linux/macOS:
kill 1234 Don't terminate a process until you know what it is and whether stopping it is safe.
Scenario B: Command Not Found
You run:
git But the shell responds:
command not found Possible causes:
- Git isn't installed.
- Git isn't in PATH.
- The current shell hasn't loaded updated environment settings.
- The executable has a different name.
Check:
command -v git PowerShell:
Get-Command git CMD:
where git If Git isn't installed, use the appropriate package manager for your platform.
Scenario C: Permission Denied
You try to execute a script:
./deploy.sh And receive:
Permission denied Check its permissions:
ls -l deploy.sh If it is your script and should be executable:
chmod +x deploy.sh Alternatively:
bash deploy.sh On Windows, permission problems may involve NTFS permissions, application access, or PowerShell execution policies. Diagnose the actual error rather than applying Unix permission commands to Windows.
Scenario D: DNS Resolution Failure
You try to access an API:
curl https://api.example.com But the hostname cannot be resolved.
Check DNS:
nslookup api.example.com Or:
dig api.example.com PowerShell:
Resolve-DnsName api.example.com Then check basic connectivity:
ping api.example.com Remember that some servers block ICMP, so a failed ping does not necessarily mean the service is unreachable.
You can also test HTTPS connectivity:
Test-NetConnection api.example.com -Port 443 Scenario E: Application Works Locally but Not on Another Device
You start a development server:
npm run dev It works on your own computer but isn't accessible from another device on the same network.
Possible causes:
- The development server listens only on
localhost. - The firewall blocks incoming connections.
- The devices are on different networks.
- The server is using an unexpected port.
For Vite, you can expose the development server to the local network:
npm run dev -- --host 0.0.0.0 Then find your local IP address.
Windows:
ipconfig Linux:
ip addr macOS:
ifconfig Open the application from another device using the host's LAN address and the development server's port.
Only expose development servers on networks you trust. Binding to 0.0.0.0 makes the service listen on all available network interfaces, which can expose it beyond the intended audience depending on your network and firewall configuration.
12. Create Your Personal Terminal Toolkit
At this point, you have learned many commands.
But you don't need to memorize all of them.
Instead, build a small collection of reusable scripts and notes.
A possible structure:
terminal-toolkit/ ├── bash/ │ ├── backup.sh │ ├── create-project.sh │ └── system-info.sh │ ├── powershell/ │ ├── Backup-Project.ps1 │ ├── Create-Project.ps1 │ └── Get-SystemInfo.ps1 │ ├── docs/ │ ├── networking.md │ ├── permissions.md │ └── troubleshooting.md │ └── README.md Keep the toolkit in a Git repository.
That gives you:
- Version history
- Reusable scripts
- Documentation
- A way to share improvements
- A personal reference for future projects
You can gradually add scripts as you discover repetitive tasks in your daily work.
13. A Professional Terminal Checklist
Before finishing this series, check whether you can perform the following tasks.
- [ ] Navigate between directories using absolute and relative paths.
- [ ] Create, copy, move, rename, and delete files.
- [ ] Search files and inspect their contents.
- [ ] Combine commands using pipes and redirection.
- [ ] Understand file permissions and administrative privileges.
- [ ] Inspect and manage running processes.
- [ ] Diagnose basic networking problems.
- [ ] Use developer-oriented terminal tools.
- [ ] Write Bash and PowerShell scripts.
- [ ] Work with variables, arguments, loops, and functions.
- [ ] Read logs and identify common errors.
- [ ] Inspect environment variables and PATH.
- [ ] Connect to remote machines using SSH.
- [ ] Diagnose port conflicts and DNS failures.
- [ ] Build reusable automation workflows.
If you can do most of these without constantly searching for examples, you're developing a strong command-line foundation.
Conclusion: The Terminal Is a Developer's Superpower
The terminal isn't an old-fashioned alternative to graphical interfaces.
It's a powerful environment for controlling your computer, automating repetitive tasks, managing remote systems, and solving problems.
Throughout this series, we've covered:
- Terminal fundamentals.
- Filesystem navigation.
- Searching and managing files.
- Pipes and command chaining.
- Users and permissions.
- Process management.
- Networking.
- Developer terminal tools.
- Shell scripting.
- Advanced workflows and troubleshooting.
The most important lesson is simple:
Don't try to memorize every command. Learn how to investigate problems, combine tools, and build workflows.
That's how you move from someone who occasionally uses the terminal to someone who can confidently work with it.
And remember: the best terminal workflow is the one that makes your work simpler, safer, and more repeatable.
Thanks for following this series!
Happy coding. 🚀
Tags: terminal productivity devtools beginners
Series: Terminal Mastery: Windows, macOS & Linux
Reading level: Intermediate

