1#!/usr/bin/env bash
2set -euo pipefail
3
4# Declare/Typeset Demonstrations
5# Shows various uses of the declare builtin for variable attributes
6
7echo "=== Declare/Typeset Demonstrations ==="
8echo
9
10# 1. Integer arithmetic with declare -i
11echo "1. Integer Arithmetic (declare -i)"
12echo "-----------------------------------"
13declare -i num1=10
14declare -i num2=20
15
16echo "num1=$num1, num2=$num2"
17num1=num1+5 # With -i, string assignment is evaluated as arithmetic
18echo "After 'num1=num1+5': num1=$num1"
19
20num2=num1*2
21echo "After 'num2=num1*2': num2=$num2"
22
23# Attempting non-integer assignment
24num1="hello" # Will be evaluated as 0
25echo "After 'num1=\"hello\"': num1=$num1(non-integer evaluates to 0)"
26
27echo
28echo
29
30# 2. Readonly variables with declare -r
31echo "2. Readonly Variables (declare -r)"
32echo "----------------------------------"
33declare -r READONLY_VAR="This cannot be changed"
34echo "READONLY_VAR=$READONLY_VAR"
35echo "Attempting to change readonly variable..."
36
37if ! READONLY_VAR="New value" 2>/dev/null; then
38 echo " ✗ Failed as expected (readonly variable)"
39fi
40
41echo
42echo
43
44# 3. Case conversion with declare -l/-u
45echo "3. Case Conversion (declare -l/-u)"
46echo "----------------------------------"
47
48# Lowercase variable
49declare -l lowercase_var
50lowercase_var="HELLO WORLD"
51echo "Set to 'HELLO WORLD', stored as: $lowercase_var"
52
53lowercase_var="MiXeD CaSe"
54echo "Set to 'MiXeD CaSe', stored as: $lowercase_var"
55
56echo
57
58# Uppercase variable
59declare -u uppercase_var
60uppercase_var="hello world"
61echo "Set to 'hello world', stored as: $uppercase_var"
62
63uppercase_var="MiXeD CaSe"
64echo "Set to 'MiXeD CaSe', stored as: $uppercase_var"
65
66echo
67echo
68
69# 4. Nameref with declare -n
70echo "4. Name References (declare -n)"
71echo "-------------------------------"
72
73original_var="Original Value"
74echo "original_var=$original_var"
75
76# Create a nameref (pointer to another variable)
77declare -n ref=original_var
78echo "Created nameref 'ref' pointing to 'original_var'"
79echo "ref=$ref"
80
81echo
82echo "Modifying through nameref..."
83ref="Modified through reference"
84echo "ref=$ref"
85echo "original_var=$original_var (also changed!)"
86
87echo
88echo
89
90# 5. Array declaration
91echo "5. Array Declaration"
92echo "--------------------"
93
94# Indexed array
95declare -a indexed_array=("apple" "banana" "cherry")
96echo "Indexed array: ${indexed_array[@]}"
97echo "Element 0: ${indexed_array[0]}"
98echo "Element 1: ${indexed_array[1]}"
99
100echo
101
102# Associative array
103declare -A assoc_array=(
104 [name]="John Doe"
105 [age]="30"
106 [city]="New York"
107)
108echo "Associative array:"
109for key in "${!assoc_array[@]}"; do
110 echo " $key = ${assoc_array[$key]}"
111done
112
113echo
114echo
115
116# 6. Export variables
117echo "6. Export Variables (declare -x)"
118echo "--------------------------------"
119declare -x EXPORTED_VAR="I am exported to child processes"
120echo "EXPORTED_VAR=$EXPORTED_VAR"
121
122# Demonstrate in subshell
123bash -c 'echo "In subshell: EXPORTED_VAR=$EXPORTED_VAR"'
124
125# Non-exported variable
126NON_EXPORTED="I stay in this shell"
127bash -c 'echo "In subshell: NON_EXPORTED=$NON_EXPORTED" || echo " ✗ Variable not available in subshell"'
128
129echo
130echo
131
132# 7. List all declared variables with attributes
133echo "7. Viewing Variable Attributes"
134echo "------------------------------"
135echo "Integer variables in this script:"
136declare -i | grep -E "(num1|num2)" || echo " (showing only num1, num2)"
137
138echo
139echo "Readonly variables in this script:"
140declare -r | grep READONLY_VAR || echo " (showing only READONLY_VAR)"
141
142echo
143echo "Exported variables (sample):"
144declare -x | grep EXPORTED_VAR || echo " (showing only EXPORTED_VAR)"
145
146echo
147echo
148
149# 8. Combining attributes
150echo "8. Combining Attributes"
151echo "-----------------------"
152declare -ir READONLY_INT=42
153echo "Readonly integer: READONLY_INT=$READONLY_INT"
154
155declare -lx lowercase_export="THIS WILL BE LOWERCASE AND EXPORTED"
156echo "Lowercase exported: lowercase_export=$lowercase_export"
157bash -c 'echo "In subshell: lowercase_export=$lowercase_export"'
158
159echo
160echo
161
162# 9. Function-local variables
163echo "9. Function-local Variables"
164echo "---------------------------"
165
166global_var="I am global"
167
168demo_function() {
169 local local_var="I am local to the function"
170 global_var="Modified in function"
171
172 echo "Inside function:"
173 echo " local_var=$local_var"
174 echo " global_var=$global_var"
175}
176
177echo "Before function call:"
178echo " global_var=$global_var"
179
180demo_function
181
182echo "After function call:"
183echo " global_var=$global_var"
184echo " local_var=${local_var:-<not defined>}"
185
186echo
187echo
188
189# 10. Printing variable information
190echo "10. Variable Information"
191echo "------------------------"
192declare -p num1 2>/dev/null || echo "num1 info not available"
193declare -p READONLY_VAR 2>/dev/null || echo "READONLY_VAR info not available"
194declare -p lowercase_var 2>/dev/null || echo "lowercase_var info not available"
195declare -p assoc_array 2>/dev/null || echo "assoc_array info not available"
196
197echo
198echo "=== Demo Complete ==="