> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bash Read-only Variable

A read-only variable in Bash is an immutable identifier whose state—whether holding an assigned value or remaining explicitly unassigned—cannot be modified, reassigned, or unset for the duration of the shell session or script execution. Once the read-only attribute is applied, the Bash interpreter enforces strict immutability at the environment level.

## Syntax and Initialization

Bash provides three primary built-in commands to apply the read-only attribute: `readonly`, `declare -r`, and `typeset -r`.

```bash theme={"dark"}

# Using the readonly built-in
readonly VAR_NAME="static_value"


# Using declare with the -r (read-only) attribute
declare -r VAR_NAME="static_value"


# Using typeset (synonymous with declare in Bash)
typeset -r VAR_NAME="static_value"
```

The read-only attribute can also be applied to an existing variable dynamically after its initial declaration:

```bash theme={"dark"}
TARGET_VAR="initial_value"
readonly TARGET_VAR
```

**Unassigned Read-only Variables**
If a variable is marked read-only without being assigned a value, it enters a permanently `unset` state. The variable cannot be assigned a value subsequently, locking it as an empty, immutable reference.

```bash theme={"dark"}
readonly EMPTY_VAR

# EMPTY_VAR is now permanently unset and cannot be initialized
```

**Arrays and Functions**
The read-only attribute extends beyond standard scalar variables. It can be applied to indexed arrays, associative arrays, and functions using specific flags:

* `-a`: Indexed arrays
* `-A`: Associative arrays
* `-f`: Functions

```bash theme={"dark"}

# Read-only indexed array
readonly -a IDX_ARRAY=("alpha" "beta")


# Read-only associative array
declare -rA ASSOC_ARRAY=([key]="value")


# Read-only function
my_func() { echo "Executing"; }
readonly -f my_func
```

## Behavioral Mechanics

When an identifier possesses the read-only attribute, the Bash interpreter intercepts and blocks state-change operations.

* **Reassignment:** Attempting to change the value triggers a standard error (`stderr`), but does not halt script execution unless the shell is running with `set -e` (exit on error).
* **Unsetting:** The `unset` built-in explicitly fails when targeting a read-only variable.

```bash theme={"dark"}
readonly CONSTANT_VAL="100"


# Attempting reassignment
CONSTANT_VAL="200"

# stderr: bash: CONSTANT_VAL: readonly variable


# Attempting to unset
unset CONSTANT_VAL

# stderr: bash: unset: CONSTANT_VAL: cannot unset: readonly variable
```

## Scope and Exporting

Read-only variables adhere to standard Bash dynamic scoping rules, but the initialization commands exhibit different default scoping behaviors when invoked inside functions:

* `readonly`: Creates a **global** variable by default, even when invoked inside a function (unless the variable was previously declared as `local` in that scope).
* `declare -r` and `typeset -r`: Automatically restrict the variable to the function's **local** scope.
* `local -r`: Explicitly enforces local scoping for a read-only variable within a function.

```bash theme={"dark"}
execute_process() {
    readonly GLOBAL_CONST="global_value"   # Globally scoped
    declare -r LOCAL_CONST="scoped_value"  # Locally scoped
    local -r EXPLICIT_LOCAL="scoped_value" # Locally scoped
}
```

To propagate a read-only variable to the environment of child processes, it must be exported. The `readonly` built-in does not support an export flag. To simultaneously export and mark a variable as read-only, use `declare -rx` (or `typeset -rx`), or apply the `export` and `readonly` commands sequentially.

```bash theme={"dark"}

# Declare, mark read-only, and export to the environment simultaneously
declare -rx ENV_CONST="exported_value"


# Equivalent syntax using sequential commands
export ENV_CONST="exported_value"
readonly ENV_CONST
```

## Introspection

The Bash interpreter maintains an internal registry of all variables with the read-only attribute. To output a list of all currently defined read-only variables in the active shell session, invoke the `readonly` command with the `-p` (print) flag.

By default, Bash formats this output using its specific extension syntax (`declare -r`), which is not POSIX-compliant. Bash only produces POSIX-compliant output (`readonly VAR="value"`) if the shell is explicitly executed in POSIX mode (`--posix`).

```bash theme={"dark"}
readonly -p

# Default Bash output format: declare -r VAR_NAME="value"

# POSIX mode output format: readonly VAR_NAME="value"
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Bash Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
