1
2 #### no expansion
3 echo {foo}
4 ## stdout: {foo}
5
6 #### incomplete trailing expansion
7 echo {a,b}_{
8 ## stdout: a_{ b_{
9 ## OK osh stdout: {a,b}_{
10
11 #### partial leading expansion
12 echo }_{a,b}
13 ## stdout: }_a }_b
14 ## OK osh stdout: }_{a,b}
15
16 #### partial leading expansion 2
17 echo {x}_{a,b}
18 ## stdout: {x}_a {x}_b
19 ## OK osh stdout: {x}_{a,b}
20
21 #### } in expansion
22 # hm they treat this the SAME. Leftmost { is matched by first }, and then
23 # there is another } as the postfix.
24 echo {a,b}}
25 ## stdout: a} b}
26 ## status: 0
27 ## OK osh stdout: {a,b}}
28 ## OK zsh stdout-json: ""
29 ## OK zsh status: 1
30
31 #### single expansion
32 echo {foo,bar}
33 ## stdout: foo bar
34
35 #### double expansion
36 echo {a,b}_{c,d}
37 ## stdout: a_c a_d b_c b_d
38
39 #### triple expansion
40 echo {0,1}{0,1}{0,1}
41 ## stdout: 000 001 010 011 100 101 110 111
42
43 #### double expansion with single and double quotes
44 echo {'a',b}_{c,"d"}
45 ## stdout: a_c a_d b_c b_d
46
47 #### expansion with mixed quotes
48 echo -{\X"b",'cd'}-
49 ## stdout: -Xb- -cd-
50
51 #### expansion with simple var
52 a=A
53 echo -{$a,b}-
54 ## stdout: -A- -b-
55
56 #### double expansion with simple var -- bash bug
57 # bash is inconsistent with the above
58 a=A
59 echo {$a,b}_{c,d}
60 ## stdout: A_c A_d b_c b_d
61 ## BUG bash stdout: b_c b_d
62
63 #### double expansion with braced variable
64 # This fixes it
65 a=A
66 echo {${a},b}_{c,d}
67 ## stdout: A_c A_d b_c b_d
68
69 #### double expansion with literal and simple var
70 a=A
71 echo {_$a,b}_{c,d}
72 ## stdout: _A_c _A_d b_c b_d
73 ## BUG bash stdout: _ _ b_c b_d
74
75 #### expansion with command sub
76 a=A
77 echo -{$(echo a),b}-
78 ## stdout: -a- -b-
79
80 #### expansion with arith sub
81 a=A
82 echo -{$((1 + 2)),b}-
83 ## stdout: -3- -b-
84
85 #### double expansion with escaped literals
86 a=A
87 echo -{\$,\[,\]}-
88 ## stdout: -$- -[- -]-
89
90 #### { in expansion
91 # bash and mksh treat this differently. bash treats the
92 # first { is a prefix. I think it's harder to read, and \{{a,b} should be
93 # required.
94 echo {{a,b}
95 ## stdout: {{a,b}
96 ## BUG bash/zsh stdout: {a {b
97
98 #### quoted { in expansion
99 echo \{{a,b}
100 ## stdout: {a {b
101
102 #### Empty expansion
103 echo a{X,,Y}b
104 ## stdout: aXb ab aYb
105
106 #### Empty alternative
107 # zsh and mksh don't do word elision, probably because they do brace expansion
108 # AFTER variable substitution.
109 argv.py {X,,Y,}
110 ## stdout: ['X', 'Y']
111 ## OK mksh/zsh stdout: ['X', '', 'Y', '']
112 ## status: 0
113
114 #### Empty alternative with empty string suffix
115 # zsh and mksh don't do word elision, probably because they do brace expansion
116 # AFTER variable substitution.
117 argv.py {X,,Y,}''
118 ## stdout: ['X', '', 'Y', '']
119 ## status: 0
120
121 #### nested brace expansion
122 echo -{A,={a,b}=,B}-
123 ## stdout: -A- -=a=- -=b=- -B-
124
125 #### triple nested brace expansion
126 echo -{A,={a,.{x,y}.,b}=,B}-
127 ## stdout: -A- -=a=- -=.x.=- -=.y.=- -=b=- -B-
128
129 #### nested and double brace expansion
130 echo -{A,={a,b}{c,d}=,B}-
131 ## stdout: -A- -=ac=- -=ad=- -=bc=- -=bd=- -B-
132
133 #### expansion on RHS of assignment
134 # I think bash's behavior is more consistent. No splitting either.
135 v={X,Y}
136 echo $v
137 ## stdout: {X,Y}
138 ## BUG mksh stdout: X Y
139
140 #### no expansion with RHS assignment
141 {v,x}=X
142 ## status: 127
143 ## stdout-json: ""
144 ## OK zsh status: 1
145
146 #### Tilde expansion
147 HOME=/home/foo
148 echo ~
149 HOME=/home/bar
150 echo ~
151 ## STDOUT:
152 /home/foo
153 /home/bar
154 ## END
155
156 #### Tilde expansion with brace expansion
157 # NOTE: osh matches mksh. Is that OK?
158 # The brace expansion happens FIRST. After that, the second token has tilde
159 # FIRST, so it gets expanded. The first token has an unexpanded tilde, because
160 # it's not in the leading position.
161 # NOTE: mksh gives different behavior! So it probably doesn't matter that
162 # much
163 HOME=/home/bob
164 echo {foo~,~}/bar
165 ## stdout: foo~/bar /home/bob/bar
166 ## OK osh/mksh stdout: foo~/bar ~/bar
167
168 #### Two kinds of tilde expansion
169 # NOTE: osh matches mksh. Is that OK?
170 # ~/foo and ~bar
171 HOME=/home/bob
172 echo ~{/src,root}
173 ## stdout: /home/bob/src /root
174 ## OK osh/mksh stdout: ~/src ~root
175
176 #### Tilde expansion come before var expansion
177 HOME=/home/bob
178 foo=~
179 echo $foo
180 foo='~'
181 echo $foo
182 # In the second instance, we expand into a literal ~, and since var expansion
183 # comes after tilde expansion, it is NOT tried again.
184 ## STDOUT:
185 /home/bob
186 ~
187 ## END
188
189 #### Number range expansion
190 echo -{1..8..3}-
191 echo -{1..10..3}-
192 ## STDOUT:
193 -1- -4- -7-
194 -1- -4- -7- -10-
195 ## N-I mksh STDOUT:
196 -{1..8..3}-
197 -{1..10..3}-
198 ## END
199
200 #### Ascending number range expansion with negative step is invalid
201 echo -{1..8..-3}-
202 ## stdout-json: ""
203 ## status: 2
204 ## BUG bash stdout: -1- -4- -7-
205 ## BUG zsh stdout: -7- -4- -1-
206 ## BUG bash/zsh status: 0
207 ## N-I mksh stdout: -{1..8..-3}-
208 ## N-I mksh status: 0
209
210 #### regression: -1 step disallowed
211 echo -{1..4..-1}-
212 ## stdout-json: ""
213 ## status: 2
214 ## BUG bash stdout: -1- -2- -3- -4-
215 ## BUG zsh stdout: -4- -3- -2- -1-
216 ## BUG bash/zsh status: 0
217 ## N-I mksh stdout: -{1..4..-1}-
218 ## N-I mksh status: 0
219
220 #### regression: 0 step disallowed
221 echo -{1..4..0}-
222 ## stdout-json: ""
223 ## status: 2
224 ## BUG bash stdout: -1- -2- -3- -4-
225 ## BUG zsh stdout: -1..4..0-
226 ## BUG bash/zsh status: 0
227 ## N-I mksh stdout: -{1..4..0}-
228 ## N-I mksh status: 0
229
230 #### Descending number range expansion with positive step is invalid
231 echo -{8..1..3}-
232 ## stdout-json: ""
233 ## status: 2
234 ## BUG bash/zsh stdout: -8- -5- -2-
235 ## BUG bash/zsh status: 0
236 ## N-I mksh stdout: -{8..1..3}-
237 ## N-I mksh status: 0
238
239 #### Descending number range expansion with negative step
240 echo -{8..1..-3}-
241 ## stdout: -8- -5- -2-
242 # zsh behavior seems clearly wrong!
243 ## BUG zsh stdout: -2- -5- -8-
244 ## N-I mksh stdout: -{8..1..-3}-
245
246 #### Singleton ranges
247 echo {1..1}-
248 echo {-9..-9}-
249 echo {-9..-9..3}-
250 echo {-9..-9..-3}-
251 echo {a..a}-
252 ## STDOUT:
253 1-
254 -9-
255 -9-
256 -9-
257 a-
258 ## END
259 ## N-I mksh STDOUT:
260 {1..1}-
261 {-9..-9}-
262 {-9..-9..3}-
263 {-9..-9..-3}-
264 {a..a}-
265 ## END
266
267 #### Singleton char ranges with steps
268 echo {a..a..2}-
269 echo {a..a..-2}-
270 ## STDOUT:
271 a-
272 a-
273 ## END
274 # zsh is considered buggy because it implements {a..a} but not {a..a..1} !
275 ## BUG zsh STDOUT:
276 {a..a..2}-
277 {a..a..-2}-
278 ## END
279 ## N-I mksh STDOUT:
280 {a..a..2}-
281 {a..a..-2}-
282 ## END
283
284 #### Char range expansion
285 echo -{a..e}-
286 ## stdout: -a- -b- -c- -d- -e-
287 ## N-I mksh stdout: -{a..e}-
288
289 #### Char range expansion with step
290 echo -{a..e..2}-
291 ## stdout: -a- -c- -e-
292 ## N-I mksh/zsh stdout: -{a..e..2}-
293
294 #### Char ranges with steps of the wrong sign
295 echo -{a..e..-2}-
296 echo -{e..a..2}-
297 ## stdout-json: ""
298 ## status: 2
299 ## BUG bash STDOUT:
300 -a- -c- -e-
301 -e- -c- -a-
302 ## END
303 ## BUG bash status: 0
304 ## N-I mksh/zsh STDOUT:
305 -{a..e..-2}-
306 -{e..a..2}-
307 ## END
308 ## BUG mksh/zsh status: 0
309
310 #### Mixed case char expansion is invalid
311 case $SH in *zsh) echo BUG; exit ;; esac
312 echo -{z..A}-
313 echo -{z..A..2}-
314 ## stdout-json: ""
315 ## status: 2
316 ## OK mksh STDOUT:
317 -{z..A}-
318 -{z..A..2}-
319 ## END
320 ## OK mksh status: 0
321 ## BUG zsh stdout: BUG
322 ## BUG zsh status: 0
323 # This is exposed a weird bash bug!!!
324 ## BUG bash stdout-json: ""
325 ## BUG bash status: 1
326
327 #### Descending char range expansion
328 echo -{e..a..-2}-
329 ## stdout: -e- -c- -a-
330 ## N-I mksh/zsh stdout: -{e..a..-2}-
331
332 #### Fixed width number range expansion
333 echo -{01..03}-
334 echo -{09..12}- # doesn't become -012-, fixed width
335 echo -{12..07}-
336 ## STDOUT:
337 -01- -02- -03-
338 -09- -10- -11- -12-
339 -12- -11- -10- -09- -08- -07-
340 ## END
341 ## N-I mksh STDOUT:
342 -{01..03}-
343 -{09..12}-
344 -{12..07}-
345 ## END
346
347 #### Inconsistent fixed width number range expansion
348 # zsh uses the first one, bash uses the max width?
349 echo -{01..003}-
350 ## stdout: -001- -002- -003-
351 ## OK zsh stdout: -01- -02- -03-
352 ## N-I mksh stdout: -{01..003}-
353
354 #### Inconsistent fixed width number range expansion
355 # zsh uses the first width, bash uses the max width?
356 echo -{01..3}-
357 ## stdout: -01- -02- -03-
358 ## N-I mksh stdout: -{01..3}-
359
360 #### Adjacent comma and range works
361 echo -{a,b}{1..3}-
362 ## STDOUT:
363 -a1- -a2- -a3- -b1- -b2- -b3-
364 ## END
365 ## N-I mksh STDOUT:
366 -a{1..3}- -b{1..3}-
367 ## END
368
369 #### Range inside comma works
370 echo -{a,_{1..3}_,b}-
371 ## STDOUT:
372 -a- -_1_- -_2_- -_3_- -b-
373 ## END
374 ## N-I mksh STDOUT:
375 -a- -_{1..3}_- -b-
376 ## END
377
378 #### Mixed comma and range doesn't work
379 echo -{a,b,1..3}-
380 ## STDOUT:
381 -a- -b- -1..3-
382 ## END
383
384 #### comma and invalid range (adjacent and nested)
385 echo -{a,b}{1...3}-
386 echo -{a,{1...3}}-
387 echo {a,b}{}
388 ## STDOUT:
389 -a{1...3}- -b{1...3}-
390 -a- -{1...3}-
391 a{} b{}
392 ## END
393 # osh doesn't expand ANYTHING on invalid syntax. That's OK because of the test
394 # case below.
395 ## OK osh STDOUT:
396 -{a,b}{1...3}-
397 -{a,{1...3}}-
398 {a,b}{}
399 ## END
400
401 #### OSH provides an alternative to invalid syntax
402 echo -{a,b}\{1...3\}-
403 echo -{a,\{1...3\}}-
404 echo {a,b}\{\}
405 ## STDOUT:
406 -a{1...3}- -b{1...3}-
407 -a- -{1...3}-
408 a{} b{}
409 ## END
410
411 #### Side effect in expansion
412 # bash is the only one that does it first. I guess since this is
413 # non-POSIX anyway, follow bash?
414 i=0
415 echo {a,b,c}-$((i++))
416 ## stdout: a-0 b-1 c-2
417 ## OK mksh/zsh stdout: a-0 b-0 c-0
418
419 #### Invalid brace expansions don't expand
420 echo {1.3}
421 echo {1...3}
422 echo {1__3}
423 ## STDOUT:
424 {1.3}
425 {1...3}
426 {1__3}
427 ## END
428
429 #### Invalid brace expansions mixing characters and numbers
430 # zsh does something crazy like : ; < = > that I'm not writing
431 case $SH in *zsh) echo BUG; exit ;; esac
432 echo {1..a}
433 echo {z..3}
434 ## STDOUT:
435 {1..a}
436 {z..3}
437 ## END
438 ## BUG zsh STDOUT:
439 BUG
440 ## END
441