1 #
2 # NOTE: Could move spec/03-glob.sh here.
3
4 #### glob double quote escape
5 echo "*.sh"
6 ## stdout: *.sh
7
8 #### glob single quote escape
9 echo "*.sh"
10 ## stdout: *.sh
11
12 #### glob backslash escape
13 echo \*.sh
14 ## stdout: *.sh
15
16 #### 1 char glob
17 cd $REPO_ROOT
18 echo [b]in
19 ## stdout: bin
20
21 #### 0 char glob -- does NOT work
22 echo []bin
23 ## stdout: []bin
24
25 #### looks like glob at the start, but isn't
26 echo [bin
27 ## stdout: [bin
28
29 #### looks like glob plus negation at the start, but isn't
30 echo [!bin
31 ## stdout: [!bin
32
33 #### glob can expand to command and arg
34 cd $REPO_ROOT
35 spec/testdata/echo.s[hz]
36 ## stdout: spec/testdata/echo.sz
37
38 #### glob after var expansion
39 touch _tmp/a.A _tmp/aa.A _tmp/b.B
40 f="_tmp/*.A"
41 g="$f _tmp/*.B"
42 echo $g
43 ## stdout: _tmp/a.A _tmp/aa.A _tmp/b.B
44
45 #### quoted var expansion with glob meta characters
46 touch _tmp/a.A _tmp/aa.A _tmp/b.B
47 f="_tmp/*.A"
48 echo "[ $f ]"
49 ## stdout: [ _tmp/*.A ]
50
51 #### glob after "$@" expansion
52 fun() {
53 echo "$@"
54 }
55 fun '_tmp/*.B'
56 ## stdout: _tmp/*.B
57
58 #### glob after $@ expansion
59 touch _tmp/b.B
60 fun() {
61 echo $@
62 }
63 fun '_tmp/*.B'
64 ## stdout: _tmp/b.B
65
66 #### no glob after ~ expansion
67 HOME=*
68 echo ~/*.py
69 ## stdout: */*.py
70
71 #### store literal globs in array then expand
72 touch _tmp/a.A _tmp/aa.A _tmp/b.B
73 g=("_tmp/*.A" "_tmp/*.B")
74 echo ${g[@]}
75 ## stdout: _tmp/a.A _tmp/aa.A _tmp/b.B
76 ## N-I dash/ash stdout-json: ""
77 ## N-I dash/ash status: 2
78
79 #### glob inside array
80 touch _tmp/a.A _tmp/aa.A _tmp/b.B
81 g=(_tmp/*.A _tmp/*.B)
82 echo "${g[@]}"
83 ## stdout: _tmp/a.A _tmp/aa.A _tmp/b.B
84 ## N-I dash/ash stdout-json: ""
85 ## N-I dash/ash status: 2
86
87 #### glob with escaped - in char class
88 touch _tmp/foo.-
89 touch _tmp/c.C
90 echo _tmp/*.[C-D] _tmp/*.[C\-D]
91 ## stdout: _tmp/c.C _tmp/c.C _tmp/foo.-
92
93 #### glob with char class expression
94 # note: mksh doesn't support [[:punct:]] ?
95 touch _tmp/e.E _tmp/foo.-
96 echo _tmp/*.[[:punct:]E]
97 ## stdout: _tmp/e.E _tmp/foo.-
98 ## BUG mksh stdout: _tmp/*.[[:punct:]E]
99
100 #### glob double quotes
101 # note: mksh doesn't support [[:punct:]] ?
102 touch _tmp/\"quoted.py\"
103 echo _tmp/\"*.py\"
104 ## stdout: _tmp/"quoted.py"
105
106 #### glob escaped
107 # - mksh doesn't support [[:punct:]] ?
108 # - python shell fails because \[ not supported!
109 touch _tmp/\[abc\] _tmp/\?
110 echo _tmp/\[???\] _tmp/\?
111 ## stdout: _tmp/[abc] _tmp/?
112
113 #### : escaped
114 touch _tmp/foo.-
115 echo _tmp/*.[[:punct:]] _tmp/*.[[:punct\:]]
116 ## stdout: _tmp/foo.- _tmp/*.[[:punct:]]
117 ## BUG mksh stdout: _tmp/*.[[:punct:]] _tmp/*.[[:punct:]]
118 ## BUG ash stdout: _tmp/foo.- _tmp/foo.-
119
120 #### Glob after var manipulation
121 touch _tmp/foo.zzz _tmp/bar.zzz
122 g='_tmp/*.zzzZ'
123 echo $g ${g%Z}
124 ## stdout: _tmp/*.zzzZ _tmp/bar.zzz _tmp/foo.zzz
125
126 #### Glob after part joining
127 touch _tmp/foo.yyy _tmp/bar.yyy
128 g='_tmp/*.yy'
129 echo $g ${g}y
130 ## stdout: _tmp/*.yy _tmp/bar.yyy _tmp/foo.yyy
131
132 #### Glob flags on file system
133 touch _tmp/-n _tmp/zzzzz
134 cd _tmp
135 echo -* hello zzzz?
136 ## stdout-json: "hello zzzzz"
137
138 #### set -o noglob
139 cd $REPO_ROOT
140 touch _tmp/spec-tmp/a.zz _tmp/spec-tmp/b.zz
141 echo _tmp/spec-tmp/*.zz
142 set -o noglob
143 echo _tmp/spec-tmp/*.zz
144 ## stdout-json: "_tmp/spec-tmp/a.zz _tmp/spec-tmp/b.zz\n_tmp/spec-tmp/*.zz\n"
145
146 #### set -o noglob (bug #698)
147 var='\z'
148 set -f
149 echo $var
150 ## STDOUT:
151 \z
152 ## END
153
154 #### shopt -s nullglob
155 argv.py _tmp/spec-tmp/*.nonexistent
156 shopt -s nullglob
157 argv.py _tmp/spec-tmp/*.nonexistent
158 ## stdout-json: "['_tmp/spec-tmp/*.nonexistent']\n[]\n"
159 ## N-I dash/mksh/ash stdout-json: "['_tmp/spec-tmp/*.nonexistent']\n['_tmp/spec-tmp/*.nonexistent']\n"
160
161 #### shopt -s failglob in command context
162 argv.py *.ZZ
163 shopt -s failglob
164 argv.py *.ZZ # nothing is printed, not []
165 echo status=$?
166 ## STDOUT:
167 ['*.ZZ']
168 status=1
169 ## END
170 ## N-I dash/mksh/ash STDOUT:
171 ['*.ZZ']
172 ['*.ZZ']
173 status=0
174 ## END
175
176 #### shopt -s failglob in loop context
177 for x in *.ZZ; do echo $x; done
178 echo status=$?
179 shopt -s failglob
180 for x in *.ZZ; do echo $x; done
181 echo status=$?
182 ## STDOUT:
183 *.ZZ
184 status=0
185 status=1
186 ## END
187 ## N-I dash/mksh/ash STDOUT:
188 *.ZZ
189 status=0
190 *.ZZ
191 status=0
192 ## END
193
194 #### shopt -s failglob in array literal context
195 myarr=(*.ZZ)
196 echo "${myarr[@]}"
197 shopt -s failglob
198 myarr=(*.ZZ)
199 echo status=$?
200 ## STDOUT:
201 *.ZZ
202 status=1
203 ## END
204 ## N-I mksh STDOUT:
205 *.ZZ
206 status=0
207 ## END
208 ## N-I dash/ash stdout-json: ""
209 ## N-I dash/ash status: 2
210
211 #### shopt -s failglob exits properly in command context with set -e
212 set -e
213 argv.py *.ZZ
214 shopt -s failglob
215 argv.py *.ZZ
216 echo status=$?
217 ## STDOUT:
218 ['*.ZZ']
219 ## END
220 ## status: 1
221 ## N-I dash/mksh/ash STDOUT:
222 ['*.ZZ']
223 ## END
224 ## N-I dash/mksh/ash status: 127
225
226 #### shopt -s failglob exits properly in loop context with set -e
227 set -e
228 for x in *.ZZ; do echo $x; done
229 echo status=$?
230 shopt -s failglob
231 for x in *.ZZ; do echo $x; done
232 echo status=$?
233 ## STDOUT:
234 *.ZZ
235 status=0
236 ## END
237 ## status: 1
238 ## N-I dash/mksh/ash STDOUT:
239 *.ZZ
240 status=0
241 ## END
242 ## N-I dash/mksh/ash status: 127
243
244 #### shopt -s failglob behavior on single line with semicolon
245 # bash behaves differently when commands are separated by a semicolon than when
246 # separated by a newline. This behavior doesn't make sense or seem to be
247 # intentional, so osh does not mimic it.
248
249 shopt -s failglob
250 echo *.ZZ; echo status=$? # bash doesn't execute the second part!
251 echo *.ZZ
252 echo status=$? # bash executes this
253
254 ## STDOUT:
255 status=1
256 ## END
257
258 ## OK osh STDOUT:
259 status=1
260 status=1
261 ## END
262
263 ## N-I dash/mksh/ash STDOUT:
264 *.ZZ
265 status=0
266 *.ZZ
267 status=0
268 ## END
269
270 #### Don't glob flags on file system with GLOBIGNORE
271 # This is a bash-specific extension.
272 expr $0 : '.*/osh$' >/dev/null && exit 99 # disabled until cd implemented
273 touch _tmp/-n _tmp/zzzzz
274 cd _tmp # this fail in osh
275 GLOBIGNORE=-*:zzzzz # colon-separated pattern list
276 echo -* hello zzzz?
277 ## stdout-json: "-* hello zzzz?\n"
278 ## N-I dash/mksh/ash stdout-json: "hello zzzzz"
279 ## status: 0
280
281 #### Splitting/Globbing doesn't happen on local assignment
282 cd $REPO_ROOT
283
284 f() {
285 # Dash splits words and globs before handing it to the 'local' builtin. But
286 # ash doesn't!
287 local foo=$1
288 echo "$foo"
289 }
290 f 'void *'
291 ## stdout: void *
292 ## BUG dash stdout-json: ""
293 ## BUG dash status: 2
294
295 #### Glob of unescaped [[] and []]
296 touch $TMP/[ $TMP/]
297 cd $TMP
298 echo [\[z] [\]z] # the right way to do it
299 echo [[z] []z] # also accepted
300 ## STDOUT:
301 [ ]
302 [ ]
303 ## END
304
305 #### Glob of negated unescaped [[] and []]
306 # osh does this "correctly" because it defers to libc!
307 touch $TMP/_G
308 cd $TMP
309 echo _[^\[z] _[^\]z] # the right way to do it
310 echo _[^[z] _[^]z] # also accepted
311 ## STDOUT:
312 _G _G
313 _G _G
314 ## END
315 ## BUG dash/mksh STDOUT:
316 _[^[z] _[^]z]
317 _[^[z] _[^]z]
318 ## END
319
320 #### PatSub of unescaped [[] and []]
321 x='[foo]'
322 echo ${x//[\[z]/<} # the right way to do it
323 echo ${x//[\]z]/>}
324 echo ${x//[[z]/<} # also accepted
325 echo ${x//[]z]/>}
326 ## STDOUT:
327 <foo]
328 [foo>
329 <foo]
330 [foo>
331 ## END
332 ## N-I dash stdout-json: ""
333 ## N-I dash status: 2
334
335 #### PatSub of negated unescaped [[] and []]
336 x='[foo]'
337 echo ${x//[^\[z]/<} # the right way to do it
338 echo ${x//[^\]z]/>}
339 echo ${x//[^[z]/<} # also accepted
340 #echo ${x//[^]z]/>} # only busybox ash interprets as ^\]
341 ## STDOUT:
342 [<<<<
343 >>>>]
344 [<<<<
345 ## END
346 # mksh is doing something very odd, ignoring ^ altogether?
347 ## BUG mksh STDOUT:
348 <foo]
349 [foo>
350 <foo]
351 ## END
352 ## N-I dash stdout-json: ""
353 ## N-I dash status: 2
354
355 #### Glob unicode char
356
357 touch $TMP/__a__
358 touch $TMP/__μ__
359 cd $TMP
360
361 echo __?__
362
363 ## STDOUT:
364 __a__ __μ__
365 ## END
366 ## BUG dash/mksh/ash STDOUT:
367 __a__
368 ## END
369 # note: zsh also passes this, but it doesn't run with this file.
370
371 #### dotglob (bash option that dashglob is roughly consistent with)
372 mkdir -p $TMP/dotglob
373 cd $TMP/dotglob
374 touch .foorc other
375
376 echo *
377 shopt -s dotglob
378 echo *
379 ## STDOUT:
380 other
381 .foorc other
382 ## END
383 ## N-I dash/mksh/ash STDOUT:
384 other
385 other
386 ## END