Skip to content
shellmap

pipInstall, upgrade, and remove Python packages from PyPI across all 5 shells

Equivalents in every shell

Bashunix
pip install requests

Ships with Python ≥ 3.4 (as `python -m pip`) and standalone via the OS package manager. Core verbs: `pip install <pkg>` (latest from PyPI), `pip install <pkg>==1.2.3` (pinned version), `pip install -r requirements.txt` (bulk install from a file), `pip install -e .` (editable install of a local project for development), `pip uninstall <pkg>`, `pip list` (installed in the active environment), `pip show <pkg>` (metadata + dep tree node), `pip freeze` (machine-readable `pkg==ver` list for requirements.txt), `pip install -U <pkg>` (upgrade). Strong recommendation: use `python -m pip install ...` instead of bare `pip install ...` — guarantees the pip you call matches the python you're using (multiple Python versions on one machine is the #1 source of "I installed it but it's not found" bugs).

Zshunix
pip install requests

Same external — Python is the same on macOS / Linux / zsh; pip is part of the Python install. macOS-specific: starting in macOS 12.3, system Python 2.7 was removed AND `pip install` against system Python 3 is blocked by PEP 668 (`error: externally-managed-environment`) — Apple wants you to use a venv. The correct macOS pattern is `python3 -m venv .venv; source .venv/bin/activate; pip install requests`. Or use `pipx` (`brew install pipx`) for CLI-tool installs — `pipx install black` installs each tool in its own isolated venv but exposes the executable globally.

Fishunix
pip install requests

Same external. Fish venv activation: `python -m venv .venv; source .venv/bin/activate.fish` — the `.fish` activator is generated by venv automatically. Once activated, `pip install requests` works as in bash. Fish-specific tip for venv discoverability: install `direnv` (`brew install direnv`) + `echo "layout python" > .envrc` — fish auto-activates the venv on `cd` into the project, deactivates on `cd` out. Without something like direnv, you'll forget which venv is active and `pip install` into the wrong env.

PowerShellwindows
pip install requests

Pip works IDENTICALLY on Windows pwsh once Python is installed (`winget install Python.Python.3.12`). The Windows-specific quirks are: (1) `python` may resolve to the Microsoft Store "Python redirector" stub on a fresh Win10/11 — the stub launches the Store, doesn't run Python; remove from `Settings → Apps → App execution aliases`; (2) `pip install` on Win-installed Python 3.11+ is NOT PEP 668-restricted (Microsoft's Python build doesn't set `EXTERNALLY-MANAGED`), so `pip install requests` works against the system Python without a venv — but venvs are still the right answer; (3) PowerShell venv activation: `.\.venv\Scripts\Activate.ps1` (note the `.ps1`, not `.fish` or no-extension). Execution policy may block — `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser` once.

cmd.exewindows
pip install requests

Identical CLI to other platforms — once Python is on `PATH`, `pip install <pkg>` works from cmd. Venv activation in cmd: `.venv\Scripts\activate.bat` (the `.bat`, not `.ps1`). Common Windows footgun: multiple Python installs on `PATH` and `pip` calls one while `python` calls another — `where python` + `where pip` show the resolution order. Always prefer `python -m pip install ...` to lock pip to the same Python `where python` resolves.

Worked examples

Install a package and freeze the result to requirements.txt

Bash
pip install requests && pip freeze > requirements.txt
Fish
pip install requests; and pip freeze > requirements.txt
PowerShell
pip install requests; pip freeze | Out-File -Encoding utf8 requirements.txt
cmd.exe
pip install requests && pip freeze > requirements.txt

Create + activate a venv, install pinned deps

Bash
python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
Fish
python -m venv .venv; and source .venv/bin/activate.fish; and pip install -r requirements.txt
PowerShell
python -m venv .venv; .\.venv\Scripts\Activate.ps1; pip install -r requirements.txt
cmd.exe
python -m venv .venv && .venv\Scripts\activate.bat && pip install -r requirements.txt

Show outdated packages, upgrade one

Bash
pip list --outdated && pip install -U requests
Fish
pip list --outdated; and pip install -U requests
PowerShell
pip list --outdated; pip install -U requests
cmd.exe
pip list --outdated && pip install -U requests

Gotchas

  • PEP 668 (`error: externally-managed-environment`) lands on most Linux distros and macOS since 2023 — `pip install` against system Python is BLOCKED. The error message points at venv as the right answer: `python -m venv .venv && source .venv/bin/activate && pip install <pkg>`. Two escape hatches that work but you shouldn't use: `pip install --break-system-packages <pkg>` (overrides PEP 668, may break system tools that depend on specific package versions) and `pip install --user <pkg>` (installs to `~/.local/`, sometimes blocked too). The correct workflow is venvs per project + `pipx` for global CLI tools.
  • Bare `pip install <pkg>` calls the FIRST `pip` on PATH, which may NOT match the `python` you run scripts with. Classic bug: `pip install requests` succeeds, then `python myscript.py` fails with `ModuleNotFoundError: No module named requests` — because `pip` was Python 3.10's and `python` is Python 3.11's. Always: `python -m pip install <pkg>` (use the pip that ships with the python you mean to run). Same fix on Windows: `python -m pip install <pkg>` instead of bare `pip`.
  • Venv activation has DIFFERENT activator scripts per shell: bash/zsh use `source .venv/bin/activate`; fish uses `source .venv/bin/activate.fish`; pwsh uses `.\.venv\Scripts\Activate.ps1` (Windows) or `.venv/bin/Activate.ps1` (Linux/macOS pwsh); cmd uses `.venv\Scripts\activate.bat`. A bash-style activate command from a fish prompt produces silent garbage — fish parses the bash script as fish syntax, doesn't error, but the venv isn't activated. Always use the activator matching your shell.
  • `pip freeze > requirements.txt` captures the FULL transitive dep tree pinned to exact versions — including transitive deps you didn't directly install. This is good for reproducibility (CI installs the exact same versions) but bad for human review (the file lists 50 packages when you actually installed 3). The modern alternative is `pip-tools` (`pip install pip-tools`, then `pip-compile requirements.in` produces `requirements.txt`) or `poetry` / `uv` (which separate "what you asked for" from "what got installed") — `requirements.in` lists your direct deps, `requirements.txt` is the locked transitive set.
  • Pip's dependency resolver (since 20.3, late 2020) is "real" — it backtracks when version constraints conflict, producing better error messages than the old "first match wins" resolver. But backtracking can be SLOW on big requirement files (`pip install -r requirements.txt` taking 5+ minutes is the smell). Mitigations: pin versions in `requirements.txt` (resolver has nothing to search), use `pip install --use-deprecated=legacy-resolver` (faster, but you get the old "may produce incompatible installs" behaviour), or switch to `uv` (`pip install uv; uv pip install -r requirements.txt`) — 10-100× faster Rust-implemented resolver.

WSL & PowerShell Core notes

pwshpip is identical on pwsh-on-any-OS — it ships with the Python you installed and the CLI is platform-agnostic. The differences are entirely about (1) which Python pwsh resolves first (use `Get-Command python` to verify), (2) the venv activator path (`.venv/bin/Activate.ps1` on Linux/macOS pwsh, `.venv\Scripts\Activate.ps1` on Windows pwsh), and (3) PEP 668 enforcement (active on Linux pwsh against system Python, off on Windows pwsh's Python installs). For cross-platform pwsh scripts that need to install Python deps, prefer `python -m pip install -r requirements.txt` inside an explicitly created venv — works identically everywhere.
WSLInside WSL Ubuntu, `pip` calls the Ubuntu Python — PEP 668 enforced since Ubuntu 23.04. Venvs in WSL must live in the WSL filesystem (`/home/<user>/...`), NOT under `/mnt/c/...` — DrvFs perf cripples Python import times (each `.py` lookup is a Windows-mediated syscall, 5-10× slower than ext4). Common bug: developer puts a venv in `/mnt/c/Code/myproj/.venv`, then wonders why `pytest` takes 30s to start; move the venv to `/home/<user>/code/myproj/.venv` and it drops to ~1s. For Windows-host Python from inside WSL: shell out via `cmd.exe /c python.exe -c "..."` (rarely useful — most workflows want one Python or the other, not both).

Related commands