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