Skip to content
shellmap

waitPause until background jobs or processes finish across all 5 shells

Equivalents in every shell

Bashunix
wait

Builtin. `wait` (no args) blocks until ALL background jobs in the current shell exit; `wait %1` waits for job number 1; `wait $PID` waits for a specific PID. Exit status echoes the awaited process.

Zshunix
wait

Same as bash. `wait %job-spec` and `wait $PID` both work. Bare `wait` collects every backgrounded job started in the current shell.

Fishunix
wait

Builtin since fish 3.0. Same `wait %1` / `wait $PID` syntax. Fish does NOT auto-reap finished jobs into `$status` — you must call `wait` to collect their exit codes.

PowerShellwindows
Wait-Process -Name notepad

Waits for an EXTERNAL process by name or PID. For PowerShell background jobs (`Start-Job`, `Start-ThreadJob`) use `Wait-Job` instead. `Wait-Process -Timeout 30` throws when the timer expires without killing the target.

cmd.exewindows
start /wait program.exe

`start /wait` is the only cmd primitive for waiting on a child process to finish before the next line runs. There is no equivalent of `wait $PID` — you launch and wait in one operation, with no way to wait for a PID launched elsewhere.

Worked examples

Wait for every background job to complete

Bash
long_job & long_job & wait
Zsh
long_job & long_job & wait
Fish
long_job & long_job & wait
PowerShell
Get-Job | Wait-Job

Wait for a specific PID and capture its exit status

Bash
long_job & PID=$!; wait $PID; echo "exit=$?"
Zsh
long_job & PID=$!; wait $PID; echo "exit=$?"
PowerShell
$p = Start-Process notepad -PassThru; $p.WaitForExit(); $p.ExitCode

Wait with a hard timeout

Bash
long_job & PID=$!; (sleep 30; kill $PID 2>/dev/null) & wait $PID
PowerShell
Wait-Process -Id $PID -Timeout 30; if (Get-Process -Id $PID -ErrorAction SilentlyContinue) { Stop-Process -Id $PID }

Gotchas

  • Bash `wait` exit status is the EXIT CODE of the LAST awaited job, not an aggregate. Five jobs in parallel where three fail still reports only one of those failures — to detect any failure, `wait` on each PID individually and OR the statuses.
  • Bare `wait` with no args BLOCKS until every background job exits — including ones already collected. Use `wait $PID1 $PID2 ...` explicitly to wait on only the targets you care about, especially in long-running scripts.
  • A PID that is NOT a child of the current shell cannot be waited on. `wait 12345` for a PID started in a different terminal returns immediately with exit status 127 (`not a child`), not actually waiting — a frequent surprise when reusing PID files.
  • PowerShell `Wait-Process -Timeout 30` does NOT kill the process when the timer expires — it just throws a non-terminating error. Follow up with `Stop-Process -Id $PID` to actually enforce the timeout.
  • Cmd `start /wait` runs the child in a NEW console window by default. Use `start /b /wait` to keep it in the current console; `/b` also blocks Ctrl-C forwarding, which can break interactive children that expect to receive the signal.

WSL & PowerShell Core notes

pwsh`Wait-Process` and `Wait-Job` work identically on Windows, Linux, and macOS pwsh. The bash idiom `cmd1 & cmd2 & wait` has no direct PowerShell port — use `$jobs = 1..2 | ForEach-Object { Start-Job ... }; $jobs | Wait-Job` to fan out and collect.
WSLWSL bash's `wait` works on Linux PIDs only. You cannot `wait` on a Windows-side process (e.g. one launched via `cmd.exe /c notepad`) — the PID is opaque to the Linux side once handed off. Keep pipelines that need `wait` entirely within one platform.

Common tasks using wait

Related commands