function — Define a reusable named function in a shell script across all 5 shells
Equivalents in every shell
greet() { echo "hi $1"; }POSIX form is `name() { body; }`. Bash also accepts `function name { body; }` and `function name() { body; }`. Arguments are `$1`, `$2`, ..., the count is `$#`, all args are `$@`. `return N` exits with status N.
greet() { echo "hi $1"; }Identical to bash. Zsh's `function name { ... }` form is preferred in zsh-only scripts because it also enables anonymous functions: `() { body }` runs the body immediately in its own scope.
function greet; echo "hi $argv[1]"; endFish uses `function NAME ... end`. Arguments live in `$argv` (a list, 1-indexed). No `return value` — fish functions implicitly return the exit status of the last command. Functions can be auto-loaded from `~/.config/fish/functions/<name>.fish`.
function Greet { param($name) "hi $name" }Functions are first-class. Named parameters via `param()`, positional via `$args`. Output is collected from EVERY uncaptured expression and returned as an array — explicit `return` is only for early exit.
call :greet WorldCmd has no `function` keyword. Use labels + `call :label arg`. Inside the label, args are `%1`, `%2`, ...; return with `goto :eof`. Variables are global unless `setlocal` is the first line of the label.
Worked examples
Define and call a simple function
greet() { echo "hi $1"; }; greet Maggiegreet() { echo "hi $1"; }; greet Maggiefunction greet; echo "hi $argv[1]"; end; greet Maggiefunction Greet { param($n) "hi $n" }; Greet MaggieReturn a value from a function
add() { echo $(($1 + $2)); }; result=$(add 1 2)add() { echo $(($1 + $2)); }; result=$(add 1 2)function add; math $argv[1] + $argv[2]; end; set result (add 1 2)function Add { param($a, $b) $a + $b }; $result = Add 1 2Local variables inside a function
f() { local x=1; echo $x; }f() { local x=1; echo $x; }function f; set -l x 1; echo $x; endfunction F { $local:x = 1; $x }Gotchas
- Bash `return` only returns an EXIT STATUS (0–255 integer), NOT a string or arbitrary value. To "return" a value, `echo` it inside the function and capture with `result=$(func)` at the call site. Returning a string via `return` silently truncates to a uint8.
- `function name() { ... }` (with parentheses AND the `function` keyword) is BASH-ONLY syntax. POSIX `sh` / dash / ash do not accept it. Use the POSIX `name() { ... }` form for any script intended to run under `/bin/sh`.
- Fish function arguments live in `$argv` (a list). `$argv[1]` is the FIRST, not `$0` or `$1` like bash. There is no equivalent of bash's `$0` for the function name — use `(status function)` instead, which returns the currently executing function's name.
- PowerShell functions ACCUMULATE all uncaptured output as the return value. `function F { "hi"; "bye" }` returns the array `@("hi","bye")`, not just "bye". Pipe unwanted output to `| Out-Null` or assign to a variable to suppress it; `return $x` alone does not discard prior output.
- Cmd `:label` "functions" SHARE all variables with the caller unless `setlocal` is the first line inside the label. `endlocal` is required before `goto :eof` if you want a value to escape; the canonical idiom is `endlocal & set "RESULT=%RESULT%"` on a single line.