1 |
#!/bin/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-json: "/home/foo\n/home/bar\n" |
153 |
|
154 |
### Tilde expansion with brace expansion |
155 |
# The brace expansion happens FIRST. After that, the second token has tilde |
156 |
# FIRST, so it gets expanded. The first token has an unexpanded tilde, because |
157 |
# it's not in the leading position. |
158 |
# NOTE: mksh gives different behavior! So it probably doesn't matter that |
159 |
# much... |
160 |
HOME=/home/bob |
161 |
echo {foo~,~}/bar |
162 |
# stdout: foo~/bar /home/bob/bar |
163 |
# OK mksh stdout: foo~/bar ~/bar |
164 |
|
165 |
### Two kinds of tilde expansion |
166 |
# ~/foo and ~bar |
167 |
HOME=/home/bob |
168 |
echo ~{/src,root} |
169 |
# stdout: /home/bob/src /root |
170 |
# OK mksh stdout: ~/src ~root |
171 |
|
172 |
### Tilde expansion come before var expansion |
173 |
HOME=/home/bob |
174 |
foo=~ |
175 |
echo $foo |
176 |
foo='~' |
177 |
echo $foo |
178 |
# In the second instance, we expand into a literal ~, and since var expansion |
179 |
# comes after tilde expansion, it is NOT tried again. |
180 |
# stdout-json: "/home/bob\n~\n" |
181 |
|
182 |
### Number range expansion |
183 |
echo -{1..8..3}- |
184 |
# stdout: -1- -4- -7- |
185 |
# N-I mksh stdout: -{1..8..3}- |
186 |
|
187 |
### Ascending number range expansion with negative step |
188 |
echo -{1..8..-3}- |
189 |
# stdout: -1- -4- -7- |
190 |
# OK zsh stdout: -7- -4- -1- |
191 |
# N-I mksh stdout: -{1..8..-3}- |
192 |
|
193 |
### Descending number range expansion |
194 |
echo -{8..1..3}- |
195 |
# stdout: -8- -5- -2- |
196 |
# N-I mksh stdout: -{8..1..3}- |
197 |
|
198 |
### Descending number range expansion with negative step |
199 |
echo -{8..1..-3}- |
200 |
# stdout: -8- -5- -2- |
201 |
# OK zsh stdout: -2- -5- -8- |
202 |
# N-I mksh stdout: -{8..1..-3}- |
203 |
|
204 |
### Char range expansion |
205 |
echo -{a..e}- |
206 |
# stdout: -a- -b- -c- -d- -e- |
207 |
# N-I mksh stdout: -{a..e}- |
208 |
|
209 |
### Char range expansion with step |
210 |
echo -{a..e..2}- -{a..e..-2}- |
211 |
# stdout: -a- -c- -e- -a- -c- -e- |
212 |
# N-I mksh/zsh stdout: -{a..e..2}- -{a..e..-2}- |
213 |
|
214 |
### Descending char range expansion |
215 |
echo -{e..a..2}- -{e..a..-2}- |
216 |
# stdout: -e- -c- -a- -e- -c- -a- |
217 |
# N-I mksh/zsh stdout: -{e..a..2}- -{e..a..-2}- |
218 |
|
219 |
### Fixed width number range expansion |
220 |
echo -{01..03}- |
221 |
# stdout: -01- -02- -03- |
222 |
# N-I mksh stdout: -{01..03}- |
223 |
|
224 |
### Inconsistent fixed width number range expansion |
225 |
# zsh uses the first one, bash uses the max width? |
226 |
echo -{01..003}- |
227 |
# stdout: -001- -002- -003- |
228 |
# OK zsh stdout: -01- -02- -03- |
229 |
# N-I mksh stdout: -{01..003}- |
230 |
|
231 |
### Inconsistent fixed width number range expansion |
232 |
# zsh uses the first width, bash uses the max width? |
233 |
echo -{01..3}- |
234 |
# stdout: -01- -02- -03- |
235 |
# N-I mksh stdout: -{01..3}- |
236 |
|
237 |
### Side effect in expansion |
238 |
# bash is the only one that does it first. I guess since this is |
239 |
# non-POSIX anyway, follow bash? |
240 |
i=0 |
241 |
echo {a,b,c}-$((i++)) |
242 |
# stdout: a-0 b-1 c-2 |
243 |
# OK mksh/zsh stdout: a-0 b-0 c-0 |