declare — Declare a variable, an array, or set variable attributes across all 5 shells
Equivalents in every shell
declare -i count=0Builtin. 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.
typeset -i count=0Zsh 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.
set -l count 0Fish 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.
[int]$count = 0A 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.
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
declare -i count=0typeset -i count=0set -l count 0[int]$count = 0set /a count=0Declare a readonly variable
declare -r MAX=100typeset -r MAX=100Set-Variable MAX 100 -Option ReadOnlyDeclare an associative array (map)
declare -A user; user[name]=alicetypeset -A user; user[name]=alice$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.