1 | ## compare_shells: bash zsh mksh ash
|
2 | ## oils_failures_allowed: 9
|
3 |
|
4 | # Note: this file elaborates on spec/ble-idioms.test.sh
|
5 |
|
6 | #### Indexed LHS without spaces, and +=
|
7 | a[1]=x
|
8 | echo status=$?
|
9 | argv.py "${a[@]}"
|
10 |
|
11 | a[0+2]=y
|
12 | #a[2|3]=y # zsh doesn't allow this
|
13 | argv.py "${a[@]}"
|
14 |
|
15 | # += does appending
|
16 | a[0+2]+=z
|
17 | argv.py "${a[@]}"
|
18 |
|
19 | ## STDOUT:
|
20 | status=0
|
21 | ['x']
|
22 | ['x', 'y']
|
23 | ['x', 'yz']
|
24 | ## END
|
25 |
|
26 | ## N-I ash status: 2
|
27 | ## N-I ash STDOUT:
|
28 | status=127
|
29 | ## END
|
30 |
|
31 | #### Indexed LHS with spaces
|
32 | case $SH in zsh|ash) exit ;; esac
|
33 |
|
34 | a[1 * 1]=x
|
35 | a[ 1 + 2 ]=z
|
36 | echo status=$?
|
37 |
|
38 | argv.py "${a[@]}"
|
39 | ## STDOUT:
|
40 | status=0
|
41 | ['x', 'z']
|
42 | ## END
|
43 | ## N-I zsh/ash STDOUT:
|
44 | ## END
|
45 |
|
46 | #### Nested a[i[0]]=0
|
47 | case $SH in zsh|ash) exit ;; esac
|
48 |
|
49 | i=(0 1 2)
|
50 |
|
51 | a[i[0]]=0
|
52 | a[ i[1] ]=1
|
53 | a[ i[2] ]=2
|
54 | a[ i[1]+i[2] ]=3
|
55 |
|
56 | argv.py "${a[@]}"
|
57 |
|
58 | ## STDOUT:
|
59 | ['0', '1', '2', '3']
|
60 | ## END
|
61 | ## N-I zsh/ash STDOUT:
|
62 | ## END
|
63 |
|
64 | #### Multiple LHS array words
|
65 | case $SH in zsh|ash) exit ;; esac
|
66 |
|
67 | a=(0 1 2)
|
68 | b=(3 4 5)
|
69 |
|
70 | #declare -p a b
|
71 |
|
72 | HOME=/home/spec-test
|
73 |
|
74 | # empty string, and tilde sub
|
75 | a[0 + 1]= b[2 + 0]=~/src
|
76 |
|
77 | typeset -p a b
|
78 |
|
79 | echo ---
|
80 |
|
81 | # In bash, this bad prefix binding prints an error, but nothing fails
|
82 | a[0 + 1]='foo' argv.py b[2 + 0]='bar'
|
83 | echo status=$?
|
84 |
|
85 | typeset -p a b
|
86 |
|
87 | ## STDOUT:
|
88 | declare -a a=([0]="0" [1]="" [2]="2")
|
89 | declare -a b=([0]="3" [1]="4" [2]="/home/spec-test/src")
|
90 | ---
|
91 | ['b[2', '+', '0]=bar']
|
92 | status=0
|
93 | declare -a a=([0]="0" [1]="" [2]="2")
|
94 | declare -a b=([0]="3" [1]="4" [2]="/home/spec-test/src")
|
95 | ## END
|
96 |
|
97 | ## OK mksh STDOUT:
|
98 | set -A a
|
99 | typeset a[0]=0
|
100 | typeset a[1]=
|
101 | typeset a[2]=2
|
102 | set -A b
|
103 | typeset b[0]=3
|
104 | typeset b[1]=4
|
105 | typeset b[2]=/home/spec-test/src
|
106 | ---
|
107 | ['b[2', '+', '0]=bar']
|
108 | status=0
|
109 | set -A a
|
110 | typeset a[0]=0
|
111 | typeset a[1]=
|
112 | typeset a[2]=2
|
113 | set -A b
|
114 | typeset b[0]=3
|
115 | typeset b[1]=4
|
116 | typeset b[2]=/home/spec-test/src
|
117 | ## END
|
118 |
|
119 | ## N-I zsh/ash STDOUT:
|
120 | ## END
|
121 |
|
122 | #### LHS array is protected with shopt -s eval_unsafe_arith, e.g. 'a[$(echo 2)]'
|
123 | case $SH in zsh|ash) exit ;; esac
|
124 |
|
125 | a=(0 1 2)
|
126 | b=(3 4 5)
|
127 | typeset -p b
|
128 |
|
129 | expr='a[$(echo 2)]'
|
130 |
|
131 | echo 'get' "${b[expr]}"
|
132 |
|
133 | b[expr]=zzz
|
134 |
|
135 | echo 'set' "${b[expr]}"
|
136 | typeset -p b
|
137 |
|
138 | ## STDOUT:
|
139 | declare -a b=([0]="3" [1]="4" [2]="5")
|
140 | get 5
|
141 | set zzz
|
142 | declare -a b=([0]="3" [1]="4" [2]="zzz")
|
143 | ## END
|
144 |
|
145 | ## OK mksh STDOUT:
|
146 | set -A b
|
147 | typeset b[0]=3
|
148 | typeset b[1]=4
|
149 | typeset b[2]=5
|
150 | get 5
|
151 | set zzz
|
152 | set -A b
|
153 | typeset b[0]=3
|
154 | typeset b[1]=4
|
155 | typeset b[2]=zzz
|
156 | ## END
|
157 |
|
158 | ## N-I zsh/ash STDOUT:
|
159 | ## END
|
160 |
|
161 | #### file named a[ is not executed
|
162 | case $SH in zsh|ash) exit ;; esac
|
163 |
|
164 | PATH=".:$PATH"
|
165 |
|
166 | for name in 'a[' 'a[5'; do
|
167 | echo "echo hi from $name: \$# args: \$@" > "$name"
|
168 | chmod +x "$name"
|
169 | done
|
170 |
|
171 | # this does not executed a[5
|
172 | a[5 + 1]=
|
173 | a[5 / 1]=y
|
174 | echo len=${#a[@]}
|
175 |
|
176 | # Not detected as assignment because there's a non-arith character
|
177 | # bash and mksh both give a syntax error
|
178 | a[5 # 1]=
|
179 |
|
180 | ## status: 1
|
181 | ## STDOUT:
|
182 | len=2
|
183 | ## END
|
184 |
|
185 | ## N-I zsh/ash status: 0
|
186 | ## N-I zsh/ash STDOUT:
|
187 | ## END
|
188 |
|
189 | #### More fragments like a[ a[5 a[5 + a[5 + 3]
|
190 |
|
191 | for name in 'a[' 'a[5'; do
|
192 | echo "echo hi from $name: \$# args: \$@" > "$name"
|
193 | chmod +x "$name"
|
194 | done
|
195 |
|
196 | # syntax error in bash
|
197 | $SH -c 'a['
|
198 | echo "a[ status=$?"
|
199 |
|
200 | $SH -c 'a[5'
|
201 | echo "a[5 status=$?"
|
202 |
|
203 | # 1 arg +
|
204 | $SH -c 'a[5 +'
|
205 | echo "a[5 + status=$?"
|
206 |
|
207 | # 2 args
|
208 | $SH -c 'a[5 + 3]'
|
209 | echo "a[5 + 3] status=$?"
|
210 |
|
211 | $SH -c 'a[5 + 3]='
|
212 | echo "a[5 + 3]= status=$?"
|
213 |
|
214 | $SH -c 'a[5 + 3]+'
|
215 | echo "a[5 + 3]+ status=$?"
|
216 |
|
217 | $SH -c 'a[5 + 3]+='
|
218 | echo "a[5 + 3]+= status=$?"
|
219 |
|
220 | # mksh doesn't issue extra parse errors
|
221 | # and it doesn't turn a[5 + 3] and a[5 + 3]+ into commands!
|
222 |
|
223 | ## STDOUT:
|
224 | a[ status=127
|
225 | a[5 status=127
|
226 | a[5 + status=127
|
227 | a[5 + 3] status=127
|
228 | a[5 + 3]= status=0
|
229 | a[5 + 3]+ status=127
|
230 | a[5 + 3]+= status=0
|
231 | ## END
|
232 |
|
233 | ## BUG bash STDOUT:
|
234 | a[ status=2
|
235 | a[5 status=2
|
236 | a[5 + status=2
|
237 | a[5 + 3] status=127
|
238 | a[5 + 3]= status=0
|
239 | a[5 + 3]+ status=127
|
240 | a[5 + 3]+= status=0
|
241 | ## END
|
242 |
|
243 | # in zsh, everything becomes "bad pattern"
|
244 |
|
245 | ## BUG-2 zsh STDOUT:
|
246 | a[ status=1
|
247 | a[5 status=1
|
248 | a[5 + status=1
|
249 | a[5 + 3] status=1
|
250 | a[5 + 3]= status=1
|
251 | a[5 + 3]+ status=1
|
252 | a[5 + 3]+= status=1
|
253 | ## END
|
254 |
|
255 | # ash behavior is consistent
|
256 |
|
257 | ## N-I ash STDOUT:
|
258 | a[ status=127
|
259 | a[5 status=127
|
260 | a[5 + status=127
|
261 | a[5 + 3] status=127
|
262 | a[5 + 3]= status=127
|
263 | a[5 + 3]+ status=127
|
264 | a[5 + 3]+= status=127
|
265 | ## END
|
266 |
|
267 | #### Are quotes allowed?
|
268 |
|
269 | # double quotes allowed in bash
|
270 | a["1"]=2
|
271 | echo status=$? len=${#a[@]}
|
272 |
|
273 | a['2']=3
|
274 | echo status=$? len=${#a[@]}
|
275 |
|
276 | # allowed in bash
|
277 | a[2 + "3"]=5
|
278 | echo status=$? len=${#a[@]}
|
279 |
|
280 | a[3 + '4']=5
|
281 | echo status=$? len=${#a[@]}
|
282 |
|
283 | ## status: 1
|
284 | ## STDOUT:
|
285 | ## END
|
286 |
|
287 | ## OK ash status: 2
|
288 |
|
289 | # syntax errors are not fatal in bash
|
290 |
|
291 | ## BUG bash status: 0
|
292 | ## BUG bash STDOUT:
|
293 | status=0 len=1
|
294 | status=1 len=1
|
295 | status=0 len=2
|
296 | status=1 len=2
|
297 | ## END
|
298 |
|
299 | #### Tricky parsing - a[ a[0]=1 ]=X a[ a[0]+=1 ]+=X
|
300 | case $SH in zsh|mksh|ash) exit ;; esac
|
301 |
|
302 | # the nested [] means we can't use regular language lookahead?
|
303 |
|
304 | echo assign=$(( z[0] = 42 ))
|
305 |
|
306 | a[a[0]=1]=X
|
307 | declare -p a
|
308 |
|
309 | a[ a[2]=3 ]=Y
|
310 | declare -p a
|
311 |
|
312 | echo ---
|
313 |
|
314 | a[ a[0]+=1 ]+=X
|
315 | declare -p a
|
316 |
|
317 | ## STDOUT:
|
318 | assign=42
|
319 | declare -a a=([0]="1" [1]="X")
|
320 | declare -a a=([0]="1" [1]="X" [2]="3" [3]="Y")
|
321 | ---
|
322 | declare -a a=([0]="2" [1]="X" [2]="3X" [3]="Y")
|
323 | ## END
|
324 |
|
325 | ## N-I zsh/mksh/ash STDOUT:
|
326 | ## END
|
327 |
|
328 | #### argv.py a[1 + 2]=
|
329 | case $SH in zsh|ash) exit ;; esac
|
330 |
|
331 | # This tests that the worse parser doesn't unconditinoally treat a[ as special
|
332 |
|
333 | a[1 + 2]= argv.py a[1 + 2]=
|
334 | echo status=$?
|
335 |
|
336 | a[1 + 2]+= argv.py a[1 + 2]+=
|
337 | echo status=$?
|
338 |
|
339 | argv.py a[3 + 4]=
|
340 |
|
341 | argv.py a[3 + 4]+=
|
342 |
|
343 | ## STDOUT:
|
344 | ['a[1', '+', '2]=']
|
345 | status=0
|
346 | ['a[1', '+', '2]+=']
|
347 | status=0
|
348 | ['a[3', '+', '4]=']
|
349 | ['a[3', '+', '4]+=']
|
350 | ## END
|
351 |
|
352 | ## N-I zsh/ash STDOUT:
|
353 | ## END
|
354 |
|
355 | #### declare builtin doesn't allow spaces
|
356 | case $SH in zsh|mksh|ash) exit ;; esac
|
357 |
|
358 | # OSH doesn't allow this
|
359 | declare a[a[0]=1]=X
|
360 | declare -p a
|
361 |
|
362 | # neither bash nor OSH allow this
|
363 | declare a[ a[2]=3 ]=Y
|
364 | declare -p a
|
365 |
|
366 | ## STDOUT:
|
367 | declare -a a=([0]="1" [1]="X")
|
368 | declare -a a=([0]="1" [1]="X" [2]="3")
|
369 | ## END
|
370 |
|
371 | ## OK osh status: 1
|
372 | ## OK osh STDOUT:
|
373 | ## END
|
374 |
|
375 | ## N-I zsh/mksh/ash STDOUT:
|
376 | ## END
|