Skip to content
shellmap

exprEvaluate an expression (POSIX arithmetic / string ops) across all 5 shells

Equivalents in every shell

Bashunix
expr 2 + 3

External in `/usr/bin/expr`. Each operand MUST be a separate argument (`expr 2+3` prints the literal `2+3`). Multiplication needs `\*` to escape glob expansion. Exit status: 0 if value non-zero/non-empty, 1 if zero/empty, 2 on syntax error. Mostly superseded by `$(( ))`.

Zshunix
expr 2 + 3

Same external. Idiomatic zsh prefers `(( count++ ))` / `$(( a + b ))` for arithmetic and `${var#prefix}` / `${var:offset:len}` for string ops. `expr` survives mostly for POSIX `/bin/sh` script portability.

Fishunix
math 2 + 3

Fish builtin (3.0+). Accepts floats and named functions: `math "sin(pi/2)"`, `math -s 2 1/3` (scale). For string ops use `string sub`, `string match`, `string length` — they replace expr's substring / match / length forms.

PowerShellwindows
2 + 3

PowerShell evaluates expressions natively — `2 + 3`, `"abc".Length`, `"hello world" -match "world"` need no helper. `[math]::Sqrt(16)` covers transcendentals. No `expr`-style argument-per-operand splitting.

cmd.exewindows
set /a result=2+3

`set /a` is the only built-in arithmetic. Integer-only, signed 32-bit. Operators: `+ - * / % & | ^ ~ << >>`. NO string-length, substring, or regex operators — string work needs `for /f` loops or PowerShell.

Worked examples

Add two numbers

Bash
expr 2 + 3
Zsh
echo $((2 + 3))
Fish
math 2 + 3
PowerShell
2 + 3
cmd.exe
set /a 2+3

Get the length of a string

Bash
expr length 'hello world'
Zsh
s='hello world'; echo ${#s}
Fish
string length 'hello world'
PowerShell
"hello world".Length

Extract a number from a tagged identifier

Bash
expr 'build-123' : '.*-\([0-9]*\)'
Fish
string match -r -- '\d+' build-123
PowerShell
if ('build-123' -match '\d+') { $Matches[0] }

Gotchas

  • `expr` REQUIRES spaces around every operator AND each operand as a separate shell argument. `expr 2+3` prints the literal `2+3`. `expr 2 * 3` glob-expands `*` to filenames — escape as `\*` or quote `"*"`. The argument-splitting model is a constant footgun.
  • Exit status INVERTS the usual convention: `0` when the result is non-zero / non-empty, `1` when zero / empty, `2` on syntax error. With `set -e` this aborts on `n=$(expr 0 + 0)` because the zero result returns 1. Wrap in `... || true` or use `$(( ))` instead.
  • Arithmetic substitution `$(( 2 + 3 ))` replaces 90 % of `expr` use cases — same POSIX guarantee, no subprocess, no escaping required. Reach for `expr` only when targeting pre-POSIX shells or one of its rarer string-op forms like `expr length` / `expr index`.
  • Fish's `math` accepts FLOATS (`math 1/3` → `0.333333`), where bash `$(( 1/3 ))` and `expr 1 / 3` return integer `0`. For decimal arithmetic in bash, pipe through `bc -l` or use `awk 'BEGIN{print 1/3}'` — bash itself has no native floating-point.
  • PowerShell has NO `expr` cmdlet and DELIBERATELY no shell-style "evaluate this string" primitive. `Invoke-Expression` exists but runs arbitrary code (the PS equivalent of `eval`) — never feed it untrusted input. For pure math, just write the expression; the parser evaluates it.

WSL & PowerShell Core notes

pwshPowerShell native arithmetic is identical on Windows, Linux, and macOS pwsh. Floating-point follows IEEE 754, so `0.1 + 0.2 -eq 0.3` is `$false`; use `[decimal]` for money or `[math]::Round($x, 2)` for display. The `[math]` class is the cross-platform companion to bash `bc`.
WSLWSL bash has the same `expr` and `$(( ))` as native Linux. Piping a math result from WSL into Windows PowerShell yields a STRING — coerce with `[int](wsl -e expr 2 + 3) + 1`. Without the cast, `+` becomes string concatenation, a frequent porting bug.

Related commands