Skip to content
shellmap

Upgrade all packages

Apply available updates to every package currently installed — bring the system to the latest patch level for the OS package manager. The "make this box current" gesture: critical for security baselines, CI base-image refresh, and recovering a stale dev machine.

How to upgrade all packages in each shell

Bashunix
sudo apt update && sudo apt upgrade -y

Debian/Ubuntu: `apt update` refreshes the index, `apt upgrade` actually installs newer versions of already-installed packages. `apt full-upgrade` (`apt-get dist-upgrade`) is stronger — it removes packages if needed to satisfy new deps. Distro variants: `sudo dnf upgrade -y` (Fedora/RHEL/Amazon Linux 2023 — `dnf` has no separate `update` step, single command), `sudo pacman -Syu` (Arch — `S`ync + `y` refresh + `u` upgrade in one flag-pile, `--noconfirm` to skip prompts), `sudo zypper update -y` (openSUSE), `sudo apk upgrade` (Alpine — no `-y`, always non-interactive), `brew upgrade` (macOS — no sudo, brew runs as the user). Rolling-release distros (Arch, Tumbleweed) upgrade EVERYTHING on every run; stable distros (Debian, Ubuntu LTS) upgrade only within the release series — for cross-release upgrades see release-upgrade notes below.

Zshunix
sudo apt update && sudo apt upgrade -y
Fishunix
sudo apt update && sudo apt upgrade -y

Same OS package manager — fish does NOT special-case package commands. CAVEAT: the `&&` chain operator works identically in fish 3.0+ (`&&` was added; older fish used `; and`). On fish < 3.0: `sudo apt update; and sudo apt upgrade -y`. For long-running upgrades you may want a fish wrapper that pings on completion: `sudo apt upgrade -y; notify-send "apt done"` (Linux) or `… ; osascript -e 'display notification "apt done"'` (macOS).

PowerShellwindows
winget upgrade --all --accept-source-agreements --accept-package-agreements

`winget upgrade --all` (winget 1.5+) upgrades every package winget tracks. `--include-unknown` adds packages whose installed version winget can't parse (often legacy installs). PowerShellGet modules separately: `Update-Module -Force` (every installed module). .NET tools: `dotnet tool update -g <tool>` per tool — there is NO `dotnet tool update -g --all` flag, scripted: `dotnet tool list -g | tail -n +3 | awk '{print $1}' | xargs -I{} dotnet tool update -g {}`. Windows OS updates (security patches): `Install-Module PSWindowsUpdate; Install-WindowsUpdate -AcceptAll -AutoReboot` (requires admin elevation).

cmd.exewindows
winget upgrade --all --accept-source-agreements --accept-package-agreements

Same `winget.exe`. Chocolatey alternative: `choco upgrade all -y` (upgrades every choco-tracked package; `-y` confirms). Scoop: `scoop update *` then `scoop update` (first refreshes the bucket index, second applies). For OS itself from cmd: `usoclient StartScan && usoclient StartInstall` (Win 10+, undocumented but works). CAVEAT: cmd has no native `sudo`; if the elevated prompt is not already open, an `upgrade --all` from a non-elevated cmd will silently skip packages that require admin (winget skips them with a "requires elevation" message in the per-package status column).

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • **`apt update` vs `apt upgrade` — refresh-then-apply, two distinct steps.** `apt update` (or `apt-get update`) ONLY refreshes the package list — it downloads `Packages.gz` files from configured repos and updates `/var/lib/apt/lists/`. It does NOT install or upgrade anything. `apt upgrade` reads the now-fresh list and installs newer versions of already-installed packages WITHOUT removing anything. `apt full-upgrade` (= `apt-get dist-upgrade`) goes further — it WILL remove packages and add new deps if needed to bring the system to the latest set. Always run `update` then `upgrade`. dnf and pacman are different: `dnf upgrade` does both refresh and apply in one command; `pacman -Syu` is also one command (`-y` is the refresh step inside the flag-pile). Tip: `apt list --upgradable` previews what `apt upgrade` would change without doing it.
  • **Rolling vs stable distros — upgrade semantics differ.** Arch / Manjaro / Tumbleweed are ROLLING — `pacman -Syu` always brings the WHOLE system to the latest upstream, including kernel and glibc. Run it weekly or you accumulate partial-upgrade hazard (NEVER do `pacman -Sy <pkg>` alone — that refreshes the index without upgrading, then installs the new pkg against partially-old deps; this breaks systems. Always full `-Syu`). Debian / Ubuntu LTS are STABLE — `apt upgrade` only patches WITHIN the release (e.g. Ubuntu 22.04 LTS stays on 22.04 forever, just newer patches). For a cross-release upgrade (22.04 → 24.04): `sudo do-release-upgrade` (Ubuntu) or `sudo apt-get dist-upgrade && update-manager -d` then GUI flow. Don't conflate the two — running `apt full-upgrade` on Ubuntu 22.04 does NOT take you to 24.04.
  • **Reboot signaling — kernel and library upgrades need it.** Debian/Ubuntu writes `/var/run/reboot-required` after an upgrade that touched the kernel or a service that can't hot-reload. CI check: `[ -f /var/run/reboot-required ] && echo REBOOT` (rc 0 → reboot pending). The reason file is `/var/run/reboot-required.pkgs` (lists which packages triggered it). RHEL/Fedora: `dnf needs-restarting -r` (rc 0 = no reboot needed, rc 1 = reboot needed). For libraries (not kernel) where running processes have the OLD lib mapped, use `needrestart` (Debian/Ubuntu) — `sudo needrestart -r i` interactively prompts to restart affected services. Arch: no built-in signal — check `pacman -Q linux` against `uname -r` to detect a kernel-upgrade-needs-reboot situation. Windows: `winget upgrade` packages that need a reboot show "Restart required" in the result column; the OS itself flags reboot via `Get-PendingReboot` (community module) or `(Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing" -Name "RebootPending" -ErrorAction SilentlyContinue) -ne $null`.
  • **Held / pinned / excluded packages — upgrades skip them silently.** Debian/Ubuntu: `apt-mark hold <pkg>` prevents upgrade; `apt-mark showhold` lists held packages; `apt-mark unhold <pkg>` releases. Common reason: keeping a specific kernel ABI for an out-of-tree driver. Fedora/RHEL: `/etc/dnf/dnf.conf` `exclude=<pkg>*` or `dnf versionlock add <pkg>` (with the `python3-dnf-plugin-versionlock` plugin). Arch: `IgnorePkg = <pkg>` in `/etc/pacman.conf`, comma-separated. Brew: `brew pin <formula>` / `brew unpin <formula>`. Always inspect holds before assuming `apt upgrade` made you current — `apt upgrade` reports "The following packages have been kept back: …" and EXITS WITH RC 0, so a CI script that only checks rc is misleading. To force a held package: `apt install --only-upgrade <pkg>` overrides the hold for that one invocation.
  • **Non-interactive CI invocations — silence prompts, accept EULAs.** The full safe form for apt: `DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade` — `confdef`/`confold` answers "keep your config file" when a package ships a new default `/etc/foo.conf`. Without it, the upgrade prompts in the terminal and CI hangs. For dnf: `dnf upgrade -y --allowerasing --skip-broken` (the `--allowerasing` lets dnf remove conflicting packages rather than abort). For pacman: `pacman -Syu --noconfirm`. winget needs `--accept-source-agreements --accept-package-agreements` on first run of each session. choco: `choco upgrade all -y --no-color --execution-timeout=14400`. brew: already non-interactive, but `HOMEBREW_NO_AUTO_UPDATE=1` skips the implicit `brew update` to save time when scripting.

Related tasks