Skip to content
shellmap

timeMeasure how long a command takes to run across all 5 shells

Equivalents in every shell

Bashunix
time some_command

Bash KEYWORD (not a regular builtin). Times the entire pipeline and reports `real`/`user`/`sys`. `TIMEFORMAT='%R'` controls the format. The external `/usr/bin/time` is a separate program — different format, can report memory with `-v`, but cannot time builtins.

Zshunix
time some_command

Same syntax as bash. Zsh's format variable is `TIMEFMT` (no `ORMAT` suffix): `TIMEFMT='%E real %U user %S sys %M kB max-rss'`. Easy to confuse with bash's `TIMEFORMAT` when porting `.bashrc` snippets.

Fishunix
time some_command

Fish builtin (since 3.0). Prints `Executed in ... fish external usercpu syscpu`. `/usr/bin/time` does NOT work cleanly on fish pipelines because fish quotes pipeline arguments differently than POSIX.

PowerShellwindows
Measure-Command { some_command }

Returns a `[TimeSpan]` covering the script block. Output of the block is DISCARDED by default — assign to `$script:result = ...` inside the block to keep both timing and result, or run twice.

cmd.exewindows
powershell -Command "Measure-Command { some_command }"

Native cmd has no stopwatch. The `time` keyword in cmd SETS the system clock — running `time some.exe` opens an interactive clock-set prompt. Shell out to PowerShell or compute the diff with the `%TIME%` env var manually.

Worked examples

Time a single command

Bash
time grep -r foo .
Zsh
time grep -r foo .
Fish
time grep -r foo .
PowerShell
Measure-Command { Select-String -Path *.txt -Pattern foo }

Time a pipeline as a whole

Bash
time (cat big.log | grep ERROR | wc -l)
Zsh
time (cat big.log | grep ERROR | wc -l)
PowerShell
Measure-Command { Get-Content big.log | Select-String ERROR | Measure-Object }

Capture timing into a variable for later analysis

Bash
START=$SECONDS; some_command; echo $((SECONDS - START))
Zsh
START=$SECONDS; some_command; echo $((SECONDS - START))
PowerShell
$t = Measure-Command { some_command }; $t.TotalSeconds

Gotchas

  • Bash `time` is a SHELL KEYWORD; `/usr/bin/time` is a separate EXTERNAL program. The keyword times builtins, pipelines, and subshells; the external times only external programs but accepts `-v` for memory + page-fault stats. They print DIFFERENT formats — scripts that parse output must pick one and stay with it.
  • `time foo > out.log` redirects only `foo`'s stdout, NOT the timing output. Bash `time` writes timing to stderr. To capture timing AND output separately, wrap in a group: `{ time foo; } 2> timing.txt > out.log`.
  • Zsh's format variable is `TIMEFMT`; bash's is `TIMEFORMAT`. Scripts that set the wrong one for the shell they run in silently fall back to the default — easy to miss because the timing still prints, just not in the expected format.
  • PowerShell `Measure-Command` DISCARDS the block's output by default. If you need both timing AND the result, write `$script:out = ...` inside the block — otherwise you must run the command twice (once for timing, once for output).
  • Cmd's `time` keyword SETS the system clock, not measures elapsed time. Typing `time some.exe` opens the interactive clock-set prompt and likely rejects the input; reach for `Measure-Command` (via PowerShell) for any real timing work on Windows.

WSL & PowerShell Core notes

pwsh`Measure-Command` returns platform-independent `TimeSpan` objects on Windows, Linux, and macOS pwsh — the result is identical everywhere. Reading bash-style `time foo` aloud in pwsh is a common porting mistake: the bare token `time` is not a keyword in PowerShell.
WSLWSL bash `time` measures the Linux-side clock; results match native Linux. Be aware that timing a command that crosses the WSL/Win32 boundary (e.g. `cmd.exe /c calc.exe`) includes the WSL-path translation and interop overhead, not just the inner program.

Common tasks using time

Related commands