Skip to content
shellmap

declareDeclare a variable, an array, or set variable attributes across all 5 shells

Equivalents in every shell

Bashunix
declare -i count=0

Builtin. Flags: `-i` integer, `-r` readonly, `-a` indexed array, `-A` associative array, `-x` export, `-f` show function bodies, `-g` global (when used inside a function). Without flags, declares a function-local variable.

Zshunix
typeset -i count=0

Zsh prefers `typeset` (which bash also accepts as a synonym for `declare`). Same core flag set, plus a few extras like `-T` (tie array to scalar) and `-U` (unique elements only). Use `typeset` in zsh-only scripts.

Fishunix
set -l count 0

Fish has no `declare`. `set` with scopes `-l` (local), `-g` (global), `-U` (universal — persisted across sessions), `-x` (export) covers all cases. Every variable is a LIST by default; there is no separate array primitive.

PowerShellwindows
[int]$count = 0

A type cast on the LHS gives a typed variable. `New-Variable -Name x -Value 1 -Option ReadOnly` creates a readonly. Variables are dynamically typed by default unless explicitly constrained with `[int]`, `[string]`, etc.

cmd.exewindows
set /a count=0

`set /a` declares an integer variable (signed 32-bit, with arithmetic-mode parsing of the RHS). Plain `set name=value` always creates a STRING. There are no arrays, no readonly, no associative variables in cmd.

Worked examples

Declare an integer variable

Bash
declare -i count=0
Zsh
typeset -i count=0
Fish
set -l count 0
PowerShell
[int]$count = 0
cmd.exe
set /a count=0

Declare a readonly variable

Bash
declare -r MAX=100
Zsh
typeset -r MAX=100
PowerShell
Set-Variable MAX 100 -Option ReadOnly

Declare an associative array (map)

Bash
declare -A user; user[name]=alice
Zsh
typeset -A user; user[name]=alice
PowerShell
$user = @{ name = 'alice' }

Gotchas

  • Bash `declare` INSIDE a function makes the variable LOCAL to that function — even without `-l`. This bites scripts that expect `declare X` at top level to be global; works at top level but means "function-local" inside a function. Use `declare -g` for global-from-inside-function.
  • Bash `declare -i x=5+3` evaluates the RHS as arithmetic — `$x` is `8`, not `5+3`. Without `-i`, you would need `((x = 5+3))` or `x=$((5+3))` to get arithmetic. The `-i` flag changes assignment semantics for the lifetime of the variable.
  • Zsh's `typeset` is the canonical name; `declare` is accepted only for bash compatibility. Always use `typeset` in zsh-only scripts for forward compatibility — `declare` may eventually be deprecated, and `typeset` flags carry richer zsh-specific behaviour.
  • POSIX `/bin/sh` does NOT have `declare` or `typeset`. Scripts intended to run under dash, ash, or busybox `sh` (e.g. Alpine, OpenWrt) must avoid both; use plain `x=value` (string) and `readonly x` for read-only — these are the only POSIX primitives.
  • PowerShell `[int]$x = "5"` SILENTLY converts the string `"5"` to the integer `5`. If the string is unparseable (`"five"`), the assignment THROWS at runtime. Bash `declare -i x=five` instead sets `$x` to `0` silently — different failure modes when ingesting untrusted input.

WSL & PowerShell Core notes

pwshPowerShell type casts (`[int]`, `[string]`, `[datetime]`) work identically on every platform. There is no equivalent of bash's "this variable shall be integer henceforth" attribute — once typed, you must replace the variable to change its type, or cast on the RHS of each assignment.
WSLInside WSL, `declare` behaves exactly as native Linux bash. Variables declared inside WSL do NOT persist to the Windows side. Export vars across the boundary with `WSLENV` (e.g. `WSLENV=PATH/l:USER`) — bare `export` does not cross the WSL/Win32 interop layer.

Common tasks using declare

Related commands