# Bash notes: Everything I need to know about bash functions


bash has functions, but they don't behave like functions in other programming languages.
instead they behave like regular shell commands.

How do regular shell commands behave? They take in arguments separated by space, they have exit status number, they can write to stdout and stderr, they can read from stdin.. and finally they can be piped to other shell commands.

Functions can do all that.

## Defining parameters and passing arguments
u can't define parameter signature in a bash function. but the passed in arguments
are accessed inside the function with positional arg vars like `$1`, `$2` etc.

And with `"$@"`, u can iterate over the passed in args in a loop.  
And with `$*`, all the passed in args will be slurped up into a single string. (So be careful.)

```sh
log() {
  timestamp=$(date -Iseconds)
  for arg in "$@"; do
    echo "[$timestamp]:$arg"
  done
}
```

calling it like `log "blah" "blue" "blay foo"` will output:

```
[2026-07-05T17:24:34+05:30]:blah
[2026-07-05T17:24:34+05:30]:blue
[2026-07-05T17:24:34+05:30]:blay foo
```

## Returning something from a function
If u want the function to return a value, use `echo` or `printf` (better) to 
write to stdout. Do this as the last part of the function body. And then at the caller
side, u can assign it to a variable using `var=$(fncall)`.

```sh
answer() {
  printf "it is %d\n" "42"
}

answer # this is a function call
b=$(answer) # this too is a function call, captured in a var
echo $b
```

A function call's exit status - an int between 0 to 255 - is the exit status
of the last command/expression that ran in that function.

But you can return a specific code preemptively with the `return` keyword. (But this isn't commonly used, and is confusing.)

```sh
answer() {
  echo "aa"
  return 254
  echo "bb" # doesn't get executed
}

answer # aa
echo $? # 254
```

Within a function, always declare local variables so as not to pollute the 
global vars defined elsewhere in the script. Do it with `local` keyword:

- declare ints with `local -i count=1`
- arrays with `local -a arr=(item1 item2 item3)`
- hashes with `local -A hash=([k1]=v1 [k2]=v2 [k3]=v3)`
- readonly var with `local -r pi="3.14"`

