Create Read-Only AKA Immutable Variables in Bash
Sometimes a little bit of extra clarity can go a long ways such as being explicit when a variable won't change.
When inside of a function in Bash you can use the local
keyword to define a
variable and it can optionally be read-only with the -r
flag, here’s a couple
of use cases and outcomes:
#!/usr/bin/env bash
set -o errexit
set -o pipefail
set -o nounset
function mutable {
local status="pending"
status="completed"
# This line will echo "completed".
echo "${status}"
}
function immutable {
local -r status="pending"
# This line throws an error: "status: readonly variable"
status="completed"
# This line is never reached.
echo "${status}"
}
mutable
immutable
If you want to declare read-only variables outside of a function you can use
declare -r status="pending"
where as declare status="pending"
or
status="pending"
are both mutable. In the read-only case you’ll get the same
error as above if you try to change it.
Keep in mind both declare
and local
are not POSIX compliant so if you need
maximum compatibility between shells you’ll want to look into other options
such as using readonly status="pending"
. I prefer to use declare -r
when I
know I don’t need POSIX compliance because declare
is used for other things
like defining associative arrays.
Lastly, it’s worth pointing out if you try to unset
a variable such as unset status
and it’s read-only then you will get an error message saying you can’t
unset read-only variables.
Being clear with your intent is helpful when reading code. If you have a large
script and see readonly
, declare -r
, or local -r
you can be confident
that nothing else will change it or if it does then the script will error out
which helps prevent accidentally overwriting a value.
The video below demonstrates all of the above.
# Demo Video
Timestamps
- 0:16 – Locally scoped read only variables in a function
- 1:13 – Use cases for using read only variables
- 1:52 – Read only variables outside of a function
- 3:12 – Making it POSIX compliant
- 5:16 – You can’t unset read only variables
When do you usually reach for using read-only variables? Let me know below.