1 ## compare_shells: bash
2
3 #### Tilde expansions in RHS of [k]=v (BashArray)
4 HOME=/home/user
5 a=([2]=~ [4]=~:~:~)
6 echo "${a[2]}"
7 echo "${a[4]}"
8 ## STDOUT:
9 /home/user
10 /home/user:/home/user:/home/user
11 ## END
12
13 #### Tilde expansions in RHS of [k]=v (BashAssoc)
14 # Note: bash-5.2 has a bug that the tilde doesn't expand on the right hand side
15 # of [key]=value. This problem doesn't happen in bash-3.1..5.1 and bash-5.3.
16 HOME=/home/user
17 declare -A a
18 declare -A a=(['home']=~ ['hello']=~:~:~)
19 echo "${a['home']}"
20 echo "${a['hello']}"
21 ## STDOUT:
22 /home/user
23 /home/user:/home/user:/home/user
24 ## END
25 ## BUG bash STDOUT:
26 ~
27 ~:~:~
28 ## END
29
30 #### index increments without [k]= (BashArray)
31 a=([100]=1 2 3 4)
32 printf 'keys: '; argv.py "${!a[@]}"
33 printf 'vals: '; argv.py "${a[@]}"
34 a=([100]=1 2 3 4 [5]=a b c d)
35 printf 'keys: '; argv.py "${!a[@]}"
36 printf 'vals: '; argv.py "${a[@]}"
37 ## STDOUT:
38 keys: ['100', '101', '102', '103']
39 vals: ['1', '2', '3', '4']
40 keys: ['5', '6', '7', '8', '100', '101', '102', '103']
41 vals: ['a', 'b', 'c', 'd', '1', '2', '3', '4']
42 ## END
43
44 #### [k]=$v and [k]="$@" (BashArray)
45 i=5
46 v='1 2 3'
47 a=($v [i]=$v)
48 printf 'keys: '; argv.py "${!a[@]}"
49 printf 'vals: '; argv.py "${a[@]}"
50
51 x=(3 5 7)
52 a=($v [i]="${x[*]}")
53 printf 'keys: '; argv.py "${!a[@]}"
54 printf 'vals: '; argv.py "${a[@]}"
55 a=($v [i]="${x[@]}")
56 printf 'keys: '; argv.py "${!a[@]}"
57 printf 'vals: '; argv.py "${a[@]}"
58 a=($v [i]=${x[*]})
59 printf 'keys: '; argv.py "${!a[@]}"
60 printf 'vals: '; argv.py "${a[@]}"
61 a=($v [i]=${x[@]})
62 printf 'keys: '; argv.py "${!a[@]}"
63 printf 'vals: '; argv.py "${a[@]}"
64 ## STDOUT:
65 keys: ['0', '1', '2', '5']
66 vals: ['1', '2', '3', '1 2 3']
67 keys: ['0', '1', '2', '5']
68 vals: ['1', '2', '3', '3 5 7']
69 keys: ['0', '1', '2', '5']
70 vals: ['1', '2', '3', '3 5 7']
71 keys: ['0', '1', '2', '5']
72 vals: ['1', '2', '3', '3 5 7']
73 keys: ['0', '1', '2', '5']
74 vals: ['1', '2', '3', '3 5 7']
75 ## END
76
77 #### [k]=$v and [k]="$@" (BashAssoc)
78 i=5
79 v='1 2 3'
80 declare -A a
81 a=([i]=$v)
82 printf 'keys: '; argv.py "${!a[@]}"
83 printf 'vals: '; argv.py "${a[@]}"
84
85 x=(3 5 7)
86 a=([i]="${x[*]}")
87 printf 'keys: '; argv.py "${!a[@]}"
88 printf 'vals: '; argv.py "${a[@]}"
89 a=([i]="${x[@]}")
90 printf 'keys: '; argv.py "${!a[@]}"
91 printf 'vals: '; argv.py "${a[@]}"
92 a=([i]=${x[*]})
93 printf 'keys: '; argv.py "${!a[@]}"
94 printf 'vals: '; argv.py "${a[@]}"
95 a=([i]=${x[@]})
96 printf 'keys: '; argv.py "${!a[@]}"
97 printf 'vals: '; argv.py "${a[@]}"
98 ## STDOUT:
99 keys: ['i']
100 vals: ['1 2 3']
101 keys: ['i']
102 vals: ['3 5 7']
103 keys: ['i']
104 vals: ['3 5 7']
105 keys: ['i']
106 vals: ['3 5 7']
107 keys: ['i']
108 vals: ['3 5 7']
109 ## END
110
111 #### append to element (BashArray)
112 hello=100
113 a=([hello]=1 [hello]+=2)
114 printf 'keys: '; argv.py "${!a[@]}"
115 printf 'vals: '; argv.py "${a[@]}"
116 a+=([hello]+=:34 [hello]+=:56)
117 printf 'keys: '; argv.py "${!a[@]}"
118 printf 'vals: '; argv.py "${a[@]}"
119 ## STDOUT:
120 keys: ['100']
121 vals: ['12']
122 keys: ['100']
123 vals: ['12:34:56']
124 ## END
125
126 #### append to element (BashAssoc)
127 declare -A a
128 hello=100
129 a=([hello]=1 [hello]+=2)
130 printf 'keys: '; argv.py "${!a[@]}"
131 printf 'vals: '; argv.py "${a[@]}"
132 a+=([hello]+=:34 [hello]+=:56)
133 printf 'keys: '; argv.py "${!a[@]}"
134 printf 'vals: '; argv.py "${a[@]}"
135 ## STDOUT:
136 keys: ['hello']
137 vals: ['12']
138 keys: ['hello']
139 vals: ['12:34:56']
140 ## END
141 # Bash >= 5.1 has a bug. Bash <= 5.0 is OK.
142 ## BUG bash STDOUT:
143 keys: ['hello']
144 vals: ['2']
145 keys: ['hello']
146 vals: ['2:34:56']
147 ## END
148
149 #### non-index forms of element (BashAssoc)
150 declare -A a
151 a=([j]=1 2 3 4)
152 echo "status=$?"
153 printf 'keys: '; argv.py "${!a[@]}"
154 printf 'vals: '; argv.py "${a[@]}"
155 ## status: 1
156 ## STDOUT:
157 ## END
158 # Bash outputs warning messages and succeeds (exit status 0)
159 ## BUG bash status: 0
160 ## BUG bash STDOUT:
161 status=0
162 keys: ['j']
163 vals: ['1']
164 ## END
165 ## BUG bash STDERR:
166 bash: line 2: a: 2: must use subscript when assigning associative array
167 bash: line 2: a: 3: must use subscript when assigning associative array
168 bash: line 2: a: 4: must use subscript when assigning associative array
169 ## END
170
171 #### Evaluation order (1)
172 # RHS of [k]=v are expanded when the initializer list is instanciated. For the
173 # indexed array, the array indices are evaluated when the array is modified.
174 i=1
175 a=([100+i++]=$((i++)) [200+i++]=$((i++)) [300+i++]=$((i++)))
176 printf 'keys: '; argv.py "${!a[@]}"
177 printf 'vals: '; argv.py "${a[@]}"
178 ## STDOUT:
179 keys: ['104', '205', '306']
180 vals: ['1', '2', '3']
181 ## END
182
183 #### Evaluation order (2)
184 # When evaluating the index, the modification to the array by the previous item
185 # of the initializer list is visible to the current item.
186 a=([0]=1+2+3 [a[0]]=10 [a[6]]=hello)
187 printf 'keys: '; argv.py "${!a[@]}"
188 printf 'vals: '; argv.py "${a[@]}"
189 ## STDOUT:
190 keys: ['0', '6', '10']
191 vals: ['1+2+3', '10', 'hello']
192 ## END
193
194 #### Evaluation order (3)
195 # RHS should be expanded before any modification to the array.
196 a=(old1 old2 old3)
197 a=("${a[2]}" "${a[0]}" "${a[1]}" "${a[2]}" "${a[0]}")
198 printf 'keys: '; argv.py "${!a[@]}"
199 printf 'vals: '; argv.py "${a[@]}"
200 a=(old1 old2 old3)
201 old1=101 old2=102 old3=103
202 new1=201 new2=202 new3=203
203 a+=([0]=new1 [1]=new2 [2]=new3 [5]="${a[2]}" [a[0]]="${a[0]}" [a[1]]="${a[1]}")
204 printf 'keys: '; argv.py "${!a[@]}"
205 printf 'vals: '; argv.py "${a[@]}"
206 ## STDOUT:
207 keys: ['0', '1', '2', '3', '4']
208 vals: ['old3', 'old1', 'old2', 'old3', 'old1']
209 keys: ['0', '1', '2', '5', '201', '202']
210 vals: ['new1', 'new2', 'new3', 'old3', 'old1', 'old2']
211 ## END
212
213 #### [k1]=v1 (BashArray)
214 # Note: This and next tests have originally been in "spec/assign.test.sh" and
215 # compared the behavior of OSH's BashAssoc and Bash's indexed array. After
216 # supporting "arr=([index]=value)" for indexed arrays, the test was adjusted
217 # and copied here. See also the corresponding tests in "spec/assign.test.sh"
218 a=([k1]=v1 [k2]=v2)
219 echo ${a["k1"]}
220 echo ${a["k2"]}
221 ## STDOUT:
222 v2
223 v2
224 ## END
225
226 #### [k1]=v1 (BashAssoc)
227 declare -A a
228 a=([k1]=v1 [k2]=v2)
229 echo ${a["k1"]}
230 echo ${a["k2"]}
231 ## STDOUT:
232 v1
233 v2
234 ## END
235
236 #### [k1]=v1 looking like brace expansions (BashAssoc)
237 declare -A a
238 a=([k2]=-{a,b}-)
239 echo ${a["k2"]}
240 ## STDOUT:
241 -{a,b}-
242 ## END
243
244 #### [k1]=v1 looking like brace expansions (BashArray)
245 a=([k2]=-{a,b}-)
246 echo ${a["k2"]}
247 ## STDOUT:
248 -{a,b}-
249 ## END
250 ## BUG bash STDOUT:
251 [k2]=-a-
252 ## END
253
254 #### BashArray cannot be changed to BashAssoc and vice versa
255 declare -a a=(1 2 3 4)
256 eval 'declare -A a=([a]=x [b]=y [c]=z)'
257 echo status=$?
258 argv.py "${a[@]}"
259
260 declare -A A=([a]=x [b]=y [c]=z)
261 eval 'declare -a A=(1 2 3 4)'
262 echo status=$?
263 argv.py $(printf '%s\n' "${A[@]}" | sort)
264 ## STDOUT:
265 status=1
266 ['1', '2', '3', '4']
267 status=1
268 ['x', 'y', 'z']
269 ## END
270
271 #### (strict_array) s+=()
272 case $SH in bash) ;; *) shopt --set strict_array ;; esac
273
274 s1=hello
275 s2=world
276
277 # Overwriting Str with a new BashArray is allowed
278 eval 's1=(1 2 3 4)'
279 echo status=$?
280 declare -p s1
281 # Promoting Str to a BashArray is disallowed
282 eval 's2+=(1 2 3 4)'
283 echo status=$?
284 declare -p s2
285 ## STDOUT:
286 status=0
287 declare -a s1=(1 2 3 4)
288 status=1
289 declare -- s2=world
290 ## END
291 ## N-I bash STDOUT:
292 status=0
293 declare -a s1=([0]="1" [1]="2" [2]="3" [3]="4")
294 status=0
295 declare -a s2=([0]="world" [1]="1" [2]="2" [3]="3" [4]="4")
296 ## END
297
298 #### (strict_array) declare -A s+=()
299 case $SH in bash) ;; *) shopt --set strict_array ;; esac
300
301 s1=hello
302 s2=world
303
304 # Overwriting Str with a new BashAssoc is allowed
305 eval 'declare -A s1=([a]=x [b]=y)'
306 echo status=$?
307 declare -p s1
308 # Promoting Str to a BashAssoc is disallowed
309 eval 'declare -A s2+=([a]=x [b]=y)'
310 echo status=$?
311 declare -p s2
312 ## STDOUT:
313 status=0
314 declare -A s1=(['a']=x ['b']=y)
315 status=1
316 declare -- s2=world
317 ## END
318 ## N-I bash STDOUT:
319 status=0
320 declare -A s1=([b]="y" [a]="x" )
321 status=0
322 declare -A s2=([0]="world" [b]="y" [a]="x" )
323 ## END
324
325 #### (strict_array) assoc=(key value ...) is not allowed
326 case $SH in bash) ;; *) shopt --set strict_array ;; esac
327
328 declare -A a=([a]=b)
329 eval "a=(1 2 3 4)"
330 declare -p a
331 ## STDOUT:
332 declare -A a=()
333 ## END
334 ## N-I bash STDOUT:
335 declare -A a=([3]="4" [1]="2" )
336 ## END