Terminal Primer — Shell Types, Admin Rights, and Everyday Commands
"Terminal," "PowerShell," "Command Prompt," "bash"… there are so many similar black windows that it gets confusing. Let's sort out how they relate. Written for people developing on Windows.
A terminal and a shell are different things
This is the number one source of confusion. They play different roles.
| Role | Examples | |
|---|---|---|
| Terminal | The screen-side app handling text input and output | Windows Terminal, VS Code's built-in terminal |
| Shell | The inner program that interprets and runs commands | Command Prompt (cmd), PowerShell, bash |
The terminal is the "container," the shell is the "contents." For example, you run the PowerShell shell inside the Windows Terminal app. When you pick "PowerShell" or "Command Prompt" from the dropdown next to Windows Terminal's + button, you are swapping the shell inside the same container.
VS Code's built-in terminal is the same story: it is a terminal, and the shell running inside it is configurable (terminal.integrated.defaultProfile.windows).
The Windows shells
Command Prompt (cmd.exe)
- Windows' oldest shell, descended from MS-DOS
- Has its own commands like
dircopydel, and runs.bat(batch) files - Not worth learning today, but it still shows up in old tool manuals and batch files. Think of it as "kept for legacy compatibility"
PowerShell
- The current standard Windows shell. Commands follow a
Verb-Nounform (Get-ChildItem,Remove-Item, …), withlsandcdprovided as aliases - Its defining feature: pipes carry objects, not text. You can filter on properties, like
Get-Process | Where-Object { $_.CPU -gt 100 } - Beware, there are two of them:
- Windows PowerShell 5.1 (
powershell.exe) — the legacy version bundled with the OS - PowerShell 7+ (
pwsh.exe) — the current version you install separately; cross-platform and more capable
- Windows PowerShell 5.1 (
.ps1scripts can be blocked by the "execution policy." On a dev machine, runningSet-ExecutionPolicy RemoteSigned -Scope CurrentUseronce is the usual fix
Git Bash
- The bash environment bundled with Git for Windows. Unix-style commands like
lsgreprmjust work on Windows - Most web-dev documentation assumes Unix-style commands, so this is the friendliest place to paste commands from articles
- Paths use
/as the separator (C:\Users\...becomes/c/Users/...)
WSL (Windows Subsystem for Linux)
- Runs a real Linux (Ubuntu etc.) on Windows. Git Bash "imitates" Unix commands; WSL is the real thing
- For Docker, Linux-first tools, or server development where production is Linux, WSL is the safe choice
- One caveat: its file system is separate from Windows (
/mnt/c/reaches the Windows side, but slowly)
So which one should you use?
- When in doubt, PowerShell (standard on Windows, nothing to install)
- If you often paste Unix-style commands from articles, Git Bash
- For Linux-first development, WSL
- Dev tools like node / npm / pnpm / git work the same from any shell, so the choice matters less than you'd think
The Linux connection — why dev docs assume Unix
The shell story becomes much clearer once you know the OS family tree. There are broadly two lineages:
Unix (the 1970s original)
├── BSD line ──→ macOS (Unix family; bash/zsh run natively in its terminal)
└── Free OSes inheriting the Unix design ──→ Linux
├── Ubuntu / Debian
├── RedHat line (CentOS etc.)
└── Alpine (Docker favorite) and many more
Windows (MS-DOS → NT line; a separate lineage from Unix)- bash, zsh, and commands like
lsgreprmare Unix-family culture. Linux and macOS live in that culture - Windows alone is on a separate branch, with its own culture of cmd and PowerShell
- That is why using Unix commands on Windows requires Git Bash (a recreation of a Unix-like environment) or WSL (running real Linux)
And why development documentation leans Unix:
- Production web servers are almost all Linux. If you deploy to Linux, having your local machine speak the same commands is convenient
- CI is Linux too. GitHub Actions'
runs-on: ubuntu-latestis Ubuntu (Linux), and workflowrun:steps execute in bash by default - Docker containers are Linux. Commands you type inside a container are Unix-style
- macOS is Unix-family, so much of the developer world lives in bash/zsh, and articles and READMEs assume it
Developing on Windows, you easily end up with "PowerShell locally, bash in CI, bash on the server." Being aware that your local shell speaks a different dialect than everything else makes it much easier to diagnose CI-only failures (path separators, environment variable syntax, missing rm -rf, etc.).
For reference, on macOS/Linux the pairing is: terminal = Terminal.app or GNOME Terminal, shell = bash or zsh (macOS's current default).
What are admin rights?
Windows accounts have normal and administrator privileges, and even an administrator's everyday apps run with normal privileges. Only when an operation affects the system does UAC (User Account Control — the dimming "Do you want to allow…?" screen) elevate you temporarily.
Open a terminal with "Run as administrator" and every command inside that shell runs elevated.
Typical cases that need admin rights
- Writing under
C:\Program FilesorC:\Windows - Editing the hosts file (
C:\Windows\System32\drivers\etc\hosts) - Starting/stopping services; using ports below 1024
- Changing the
HKEY_LOCAL_MACHINEside of the registry - Some installers; some
winget installpackages
How to live with it as a developer
- Normal privileges are enough for daily work. npm install, git, and project builds do not need admin rights
- Worse, "running as admin made the error go away" is a dangerous habit: papering over permissions mixes up file ownership and breeds new errors later
- When needed, open one elevated Windows Terminal tab (right-click in the Start menu → Run as administrator)
- Linux/macOS's
sudo commandis the "elevate just this command" equivalent. Windows 11 now ships asudocommand too — enable it in Settings for the same feel
Everyday command table
The same task needs different commands in different shells. PowerShell ships Unix-flavored aliases, so there is less to memorize than you'd fear.
| Task | cmd | PowerShell | bash (Git Bash/WSL) |
|---|---|---|---|
| List files | dir |
ls (Get-ChildItem) |
ls -la |
| Change directory | cd |
cd |
cd |
| Show current directory | cd |
pwd |
pwd |
| Create a folder | mkdir |
mkdir |
mkdir -p |
| Delete a file | del |
rm (Remove-Item) |
rm |
| Delete a folder tree | rmdir /s |
rm -r -fo |
rm -rf |
| Copy | copy |
cp (Copy-Item) |
cp -r |
| Move / rename | move |
mv (Move-Item) |
mv |
| Show file contents | type |
cat (Get-Content) |
cat |
| Search text | findstr |
Select-String |
grep |
| Locate a command | where |
Get-Command |
which |
| Clear the screen | cls |
clear (cls works) |
clear |
| Show an env variable | echo %PATH% |
$env:PATH |
echo $PATH |
| Set an env variable | set NAME=x |
$env:NAME = "x" |
export NAME=x |
A few gotchas:
- PowerShell's
lsandrmlook like bash but take entirely different options.rm -rfdoes not work in PowerShell (Remove-Item -Recurse -Force) - Environment variables: cmd uses
%NAME%, PowerShell uses$env:NAME, bash uses$NAME. When a pasted command fails, suspect this first - Quote paths containing spaces with
". In PowerShell, launching an executable at a space-containing path needs the call operator&up front:& "C:\Program Files\App\app.exe"
The ones you type every day
Development commands that are the same in every shell:
git status # check what changed
git log --oneline # compact history
pnpm install # install dependencies
pnpm dev # start the dev server
npx serve out # serve static files quickly
node script.js # run a scriptCtrl+C interrupts the running command, ↑ recalls history, Tab completes paths. These three keystrokes alone double your effective speed.
Summary
- Terminal = container, shell = contents. PowerShell or bash runs inside Windows Terminal or VS Code's terminal
- Windows shells: cmd (legacy) / PowerShell (standard) / Git Bash (Unix-style) / WSL (real Linux). Default to PowerShell; prefer Git Bash if you paste from Unix-centric articles
- OSes come in two lineages: Unix-family (Linux, macOS) and Windows. Servers, CI, and Docker are Linux, hence the bash-first documentation culture
- Admin rights: elevate only when needed. Daily development does not require them
- Every shell has its dialect. When a command fails, check env-var syntax and option differences first