1
2 #### Lazy Evaluation of Alternative
3 i=0
4 x=x
5 echo ${x:-$((i++))}
6 echo $i
7 echo ${undefined:-$((i++))}
8 echo $i # i is one because the alternative was only evaluated once
9 ## status: 0
10 ## stdout-json: "x\n0\n0\n1\n"
11 ## N-I dash status: 2
12 ## N-I dash stdout-json: "x\n0\n"
13
14 #### Default value when empty
15 empty=''
16 echo ${empty:-is empty}
17 ## stdout: is empty
18
19 #### Default value when unset
20 echo ${unset-is unset}
21 ## stdout: is unset
22
23 #### Unquoted with array as default value
24 set -- '1 2' '3 4'
25 argv.py X${unset=x"$@"x}X
26 argv.py X${unset=x$@x}X # If you want OSH to split, write this
27 # osh
28 ## STDOUT:
29 ['Xx1', '2', '3', '4xX']
30 ['Xx1', '2', '3', '4xX']
31 ## END
32 ## OK osh STDOUT:
33 ['Xx1 2', '3 4xX']
34 ['Xx1', '2', '3', '4xX']
35 ## END
36
37 #### Quoted with array as default value
38 set -- '1 2' '3 4'
39 argv.py "X${unset=x"$@"x}X"
40 argv.py "X${unset=x$@x}X" # OSH is the same here
41 ## STDOUT:
42 ['Xx1 2 3 4xX']
43 ['Xx1 2 3 4xX']
44 ## END
45 ## BUG bash STDOUT:
46 ['Xx1', '2', '3', '4xX']
47 ['Xx1 2 3 4xX']
48 ## END
49 ## OK osh STDOUT:
50 ['Xx1 2', '3 4xX']
51 ['Xx1 2 3 4xX']
52 ## END
53
54 #### Assign default with array
55 set -- '1 2' '3 4'
56 argv.py X${unset=x"$@"x}X
57 argv.py "$unset"
58 ## STDOUT:
59 ['Xx1', '2', '3', '4xX']
60 ['x1 2 3 4x']
61 ## END
62 ## OK osh STDOUT:
63 ['Xx1 2', '3 4xX']
64 ['x1 2 3 4x']
65 ## END
66
67 #### Assign default value when empty
68 empty=''
69 ${empty:=is empty}
70 echo $empty
71 ## stdout: is empty
72
73 #### Assign default value when unset
74 ${unset=is unset}
75 echo $unset
76 ## stdout: is unset
77
78 #### ${v:+foo} Alternative value when empty
79 v=foo
80 empty=''
81 echo ${v:+v is not empty} ${empty:+is not empty}
82 ## stdout: v is not empty
83
84 #### ${v+foo} Alternative value when unset
85 v=foo
86 echo ${v+v is not unset} ${unset:+is not unset}
87 ## stdout: v is not unset
88
89 #### "${x+foo}" quoted (regression)
90 # Python's configure caught this
91 argv.py "${with_icc+set}" = set
92 ## STDOUT:
93 ['', '=', 'set']
94 ## END
95
96 #### ${v+foo} and ${v:+foo} when set -u
97 set -u
98 v=v
99 echo v=${v:+foo}
100 echo v=${v+foo}
101 unset v
102 echo v=${v:+foo}
103 echo v=${v+foo}
104 ## STDOUT:
105 v=foo
106 v=foo
107 v=
108 v=
109 ## END
110
111 #### ${v-foo} and ${v:-foo} when set -u
112 set -u
113 v=v
114 echo v=${v:-foo}
115 echo v=${v-foo}
116 unset v
117 echo v=${v:-foo}
118 echo v=${v-foo}
119 ## STDOUT:
120 v=v
121 v=v
122 v=foo
123 v=foo
124 ## END
125
126 #### array and - and +
127 case $SH in (dash) exit ;; esac
128
129 shopt -s compat_array # to refer to array as scalar
130
131 empty=()
132 a1=('')
133 a2=('' x)
134 a3=(3 4)
135 echo empty=${empty[@]-minus}
136 echo a1=${a1[@]-minus}
137 echo a1[0]=${a1[0]-minus}
138 echo a2=${a2[@]-minus}
139 echo a3=${a3[@]-minus}
140 echo ---
141
142 echo empty=${empty[@]+plus}
143 echo a1=${a1[@]+plus}
144 echo a1[0]=${a1[0]+plus}
145 echo a2=${a2[@]+plus}
146 echo a3=${a3[@]+plus}
147 echo ---
148
149 echo empty=${empty+plus}
150 echo a1=${a1+plus}
151 echo a2=${a2+plus}
152 echo a3=${a3+plus}
153 echo ---
154
155 # Test quoted arrays too
156 argv.py "${empty[@]-minus}"
157 argv.py "${empty[@]+plus}"
158 argv.py "${a1[@]-minus}"
159 argv.py "${a1[@]+plus}"
160 argv.py "${a1[0]-minus}"
161 argv.py "${a1[0]+plus}"
162 argv.py "${a2[@]-minus}"
163 argv.py "${a2[@]+plus}"
164 argv.py "${a3[@]-minus}"
165 argv.py "${a3[@]+plus}"
166
167 ## STDOUT:
168 empty=minus
169 a1=
170 a1[0]=
171 a2= x
172 a3=3 4
173 ---
174 empty=
175 a1=plus
176 a1[0]=plus
177 a2=plus
178 a3=plus
179 ---
180 empty=
181 a1=plus
182 a2=plus
183 a3=plus
184 ---
185 ['minus']
186 []
187 ['']
188 ['plus']
189 ['']
190 ['plus']
191 ['', 'x']
192 ['plus']
193 ['3', '4']
194 ['plus']
195 ## END
196 ## N-I dash stdout-json: ""
197
198 #### $@ and - and +
199 echo argv=${@-minus}
200 echo argv=${@+plus}
201 echo argv=${@:-minus}
202 echo argv=${@:+plus}
203 ## STDOUT:
204 argv=minus
205 argv=
206 argv=minus
207 argv=
208 ## END
209 ## BUG dash STDOUT:
210 argv=
211 argv=plus
212 argv=minus
213 argv=
214 ## END
215
216 #### assoc array and - and +
217 case $SH in (dash|mksh) exit ;; esac
218
219 declare -A empty=()
220 declare -A assoc=(['k']=v)
221
222 echo empty=${empty[@]-minus}
223 echo empty=${empty[@]+plus}
224 echo assoc=${assoc[@]-minus}
225 echo assoc=${assoc[@]+plus}
226
227 echo ---
228 echo empty=${empty[@]:-minus}
229 echo empty=${empty[@]:+plus}
230 echo assoc=${assoc[@]:-minus}
231 echo assoc=${assoc[@]:+plus}
232 ## STDOUT:
233 empty=minus
234 empty=
235 assoc=v
236 assoc=plus
237 ---
238 empty=minus
239 empty=
240 assoc=v
241 assoc=plus
242 ## END
243 ## N-I dash/mksh stdout-json: ""
244
245
246 #### Error when empty
247 empty=''
248 echo ${empty:?'is em'pty} # test eval of error
249 echo should not get here
250 ## stdout-json: ""
251 ## status: 1
252 ## OK dash status: 2
253
254 #### Error when unset
255 echo ${unset?is empty}
256 echo should not get here
257 ## stdout-json: ""
258 ## status: 1
259 ## OK dash status: 2
260
261 #### Error when unset
262 v=foo
263 echo ${v+v is not unset} ${unset:+is not unset}
264 ## stdout: v is not unset
265
266 #### ${var=x} dynamic scope
267 f() { : "${hello:=x}"; echo $hello; }
268 f
269 echo hello=$hello
270
271 f() { hello=x; }
272 f
273 echo hello=$hello
274 ## STDOUT:
275 x
276 hello=x
277 hello=x
278 ## END
279
280 #### array ${arr[0]=x}
281 arr=()
282 echo ${#arr[@]}
283 : ${arr[0]=x}
284 echo ${#arr[@]}
285 ## STDOUT:
286 0
287 1
288 ## END
289 ## N-I dash status: 2
290 ## N-I dash stdout-json: ""
291
292 #### assoc array ${arr["k"]=x}
293 # note: this also works in zsh
294
295 declare -A arr=()
296 echo ${#arr[@]}
297 : ${arr['k']=x}
298 echo ${#arr[@]}
299 ## STDOUT:
300 0
301 1
302 ## END
303 ## N-I dash status: 2
304 ## N-I dash stdout-json: ""
305 ## N-I mksh status: 1
306 ## N-I mksh stdout-json: ""
307
308 #### "\z" as arg
309 echo "${undef-\$}"
310 echo "${undef-\(}"
311 echo "${undef-\z}"
312 echo "${undef-\"}"
313 echo "${undef-\`}"
314 echo "${undef-\\}"
315 ## STDOUT:
316 $
317 \(
318 \z
319 "
320 `
321 \
322 ## END
323 ## BUG yash STDOUT:
324 $
325 (
326 z
327 "
328 `
329 \
330 ## END
331
332 #### "\e" as arg
333 echo "${undef-\e}"
334 ## STDOUT:
335 \e
336 ## END
337 ## BUG zsh/mksh stdout-repr: '\x1b\n'
338 ## BUG yash stdout: e
339