exit — Exit a shell or script with a status code in bash, zsh, fish, PowerShell, and cmd across all 5 shells
Equivalents in every shell
exit 0bash builtin. Status code 0–255 (values >255 wrap modulo 256). Without arg, exits with the status of the LAST command (`$?`). Inside a function, `exit` terminates the SHELL, not just the function — use `return` for function-only. From a non-interactive shell, exit also closes the pipeline.
exit 0zsh builtin, same semantics as bash. zsh has additional `exit_handler` hooks via `zshexit` function — define it to run cleanup before the shell quits. Returns LAST command status by default if no arg.
exit 0fish builtin. Same 0–255 status range. Fish exposes the last status as `$status` (not `$?`), and `set -q status` is the idiomatic check. Fish `exit` from a function exits the SCRIPT (matching bash semantics — `return` is function-only).
exit 0pwsh statement (not a cmdlet). Status 0–255 same range. Inside a function, `exit` terminates the SCRIPT / session, not just the function — use `return` for function-only. For native commands invoked from pwsh, the exit status surfaces in `$LASTEXITCODE` (separate from `$?` which is a boolean success/fail).
exit /b 0`exit` alone closes the ENTIRE cmd window — almost never what you want in a script. `exit /b N` exits only the current batch script with status `N`, returning control to the parent. The status sets `%ERRORLEVEL%` in the caller; `echo Exit was %ERRORLEVEL%` after the call reads it.
Worked examples
Exit a script with success after a check passes
if [ -f config.json ]; then echo "OK"; exit 0; else echo "missing"; exit 1; fiif test -f config.json; echo OK; exit 0; else; echo missing; exit 1; endif (Test-Path config.json) { "OK"; exit 0 } else { "missing"; exit 1 }if exist config.json (echo OK & exit /b 0) else (echo missing & exit /b 1)Exit a script propagating the status of the last command
curl -fsS https://api.example.com/health
exit $?curl -fsS https://api.example.com/health
exit $statuscurl.exe -fsS https://api.example.com/health
exit $LASTEXITCODEcurl -fsS https://api.example.com/health
exit /b %ERRORLEVEL%Standard exit codes — 0=success, 1=general error, 2=misuse, 126=cannot-execute, 127=not-found
command -v nonexistent || exit 127if (-not (Get-Command nonexistent -ErrorAction SilentlyContinue)) { exit 127 }Gotchas
- Exit codes are 8-bit (0–255). `exit 300` becomes `exit 44` (300 mod 256). For richer error signaling, write to stderr / log and use 1–125 to encode meaningful errors — reserving 126/127/128+N for shell-defined conditions (cannot-execute, not-found, signal-terminated).
- cmd `exit` (without `/b`) CLOSES THE CONSOLE WINDOW. Running `exit 1` in a `.bat` script that's double-clicked closes the window — losing all output. Always use `exit /b N` in batch files; bare `exit` is for cleaning up an interactive cmd session.
- pwsh inside a function: `exit 1` terminates the ENTIRE script, not just the function. To "return early with a status from a function", do `return $false` (and let the caller decide), or have the function `throw` and let `$LASTEXITCODE` / try/catch surface it.
- In a pipeline, the exit status returned by `$?` reflects only the LAST command — not any failing intermediate. Use `set -o pipefail` (bash) to fail the pipeline on any non-zero, or check `${PIPESTATUS[@]}` array. fish: `pipestatus` variable. pwsh: `$?` is also last-only; check `$LASTEXITCODE` after each native call.
- `exit 0` in a sourced (dot-included) script kills the PARENT shell, not just the source. `source ./script.sh && echo continue` won't print "continue" if script.sh runs `exit 0`. Use `return 0` for "successful end of sourced script" — bash/zsh allow `return` at the top level of sourced files.