Skip to content
shellmap

continueSkip a loop iteration in bash, zsh, fish, PowerShell, and cmd across all 5 shells

Equivalents in every shell

Bashunix
for i in 1 2 3; do [ "$i" = "2" ] && continue; echo "$i"; done

bash builtin. `continue N` skips to the next iteration of the N-th enclosing loop. Works in `for`, `while`, `until`, `select`. Like `break`, can be called from a function invoked inside a loop.

Zshunix
for i in 1 2 3; do [[ $i = 2 ]] && continue; echo $i; done

zsh builtin, same semantics as bash with `continue N`. Works in `repeat`, `for`, `while`, `until`, `select`.

Fishunix
for i in 1 2 3; if test $i = 2; continue; end; echo $i; end

fish builtin. Single-level only — NO `continue N`. To skip multiple levels, restructure with flag variables or extract inner logic to a function with early return.

PowerShellwindows
foreach ($i in 1..3) { if ($i -eq 2) { continue }; $i }

pwsh keyword. Supports LABELED continue: `:outer foreach (...) { foreach (...) { continue outer } }` skips to the next iteration of the outer loop. Unique among shells — same idiom as labeled break.

cmd.exewindows
for %i in (1 2 3) do (if not "%i"=="2" echo %i)

cmd has NO `continue` keyword. The idiom is to invert the condition and skip the loop body conditionally: `if NOT condition (loop_body)`. For complex bodies, factor into a `call :subroutine` and `goto :continue_label` at the top.

Worked examples

Process all files except those starting with a dot

Bash
for f in *; do [[ "$f" == .* ]] && continue; echo "$f"; done
PowerShell
foreach ($f in Get-ChildItem) { if ($f.Name -like ".*") { continue }; $f.Name }

Skip iterations of an outer loop based on inner condition (labeled continue)

PowerShell
:outer foreach ($file in Get-ChildItem *.log) { foreach ($line in Get-Content $file) { if ($line -match "ABORT") { continue outer } } "$($file.Name) is clean" }
Bash
for f in *.log; do skip=0; while IFS= read -r line; do if [[ "$line" == *ABORT* ]]; then skip=1; break; fi; done < "$f"; [ "$skip" = "1" ] && continue; echo "$f is clean"; done

Skip empty lines while reading a config file

Bash
while IFS= read -r line; do [ -z "$line" ] && continue; echo "$line"; done < config.txt
Fish
while read -l line; if test -z "$line"; continue; end; echo $line; end < config.txt
PowerShell
Get-Content config.txt | ForEach-Object { if ([string]::IsNullOrWhiteSpace($_)) { return }; $_ }

Gotchas

  • fish has NO multi-level `continue N` — same as `break`. Restructure with flag variables or extract logic to a function.
  • pwsh inside `ForEach-Object` (the pipeline cmdlet, not the foreach keyword): `continue` and `break` behave DIFFERENTLY. Inside a `ForEach-Object` script block, `return` skips the current item (analogue of `continue`); `break` terminates the entire pipeline. The `foreach` KEYWORD has the normal `continue`/`break` semantics. This is a famous footgun — read up on the distinction before mixing the two forms.
  • bash `continue` in a subshell-loop (`echo X | while read; do continue; done`) only affects the subshell's loop. Parent-loop `continue` from inside a subshell pipeline doesn't work — the subshell exits, parent loop continues normally.
  • cmd lacks `continue` entirely. The `if NOT condition ()` inversion handles simple cases; complex skip-logic requires factoring loop bodies into subroutines.
  • In an `until` loop, `continue` jumps back to the condition test — same as in `while`. The negation in `until` doesn't affect how `continue` flows; the loop continues until the condition becomes true.

WSL & PowerShell Core notes

pwshpwsh `continue` is identical across Windows / Linux / macOS pwsh. The labeled form (`continue label`) lets you skip outer-loop iterations without flag variables — the most ergonomic of the shell-language options for nested loops.
WSLWSL bash `continue` works as on Linux. Cross-shell pipelines (`cmd.exe /c X | while read line`) inherit bash's `continue` semantics from the WSL side.

Related commands