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 fun() {
60 echo $@
61 }
62 fun '_tmp/*.B'
63 ## stdout: _tmp/b.B
64
65 #### no glob after ~ expansion
66 HOME=*
67 echo ~/*.py
68 ## stdout: */*.py
69
70 #### store literal globs in array then expand
71 touch _tmp/a.A _tmp/aa.A _tmp/b.B
72 g=("_tmp/*.A" "_tmp/*.B")
73 echo ${g[@]}
74 ## stdout: _tmp/a.A _tmp/aa.A _tmp/b.B
75 ## N-I dash/ash stdout-json: ""
76 ## N-I dash/ash status: 2
77
78 #### glob inside array
79 touch _tmp/a.A _tmp/aa.A _tmp/b.B
80 g=(_tmp/*.A _tmp/*.B)
81 echo "${g[@]}"
82 ## stdout: _tmp/a.A _tmp/aa.A _tmp/b.B
83 ## N-I dash/ash stdout-json: ""
84 ## N-I dash/ash status: 2
85
86 #### glob with escaped - in char class
87 touch _tmp/foo.-
88 touch _tmp/c.C
89 echo _tmp/*.[C-D] _tmp/*.[C\-D]
90 ## stdout: _tmp/c.C _tmp/c.C _tmp/foo.-
91
92 #### glob with char class expression
93 # note: mksh doesn't support [[:punct:]] ?
94 touch _tmp/e.E _tmp/foo.-
95 echo _tmp/*.[[:punct:]E]
96 ## stdout: _tmp/e.E _tmp/foo.-
97 ## BUG mksh stdout: _tmp/*.[[:punct:]E]
98
99 #### glob double quotes
100 # note: mksh doesn't support [[:punct:]] ?
101 touch _tmp/\"quoted.py\"
102 echo _tmp/\"*.py\"
103 ## stdout: _tmp/"quoted.py"
104
105 #### glob escaped
106 # - mksh doesn't support [[:punct:]] ?
107 # - python shell fails because \[ not supported!
108 touch _tmp/\[abc\] _tmp/\?
109 echo _tmp/\[???\] _tmp/\?
110 ## stdout: _tmp/[abc] _tmp/?
111
112 #### : escaped
113 touch _tmp/foo.-
114 echo _tmp/*.[[:punct:]] _tmp/*.[[:punct\:]]
115 ## stdout: _tmp/foo.- _tmp/*.[[:punct:]]
116 ## BUG mksh stdout: _tmp/*.[[:punct:]] _tmp/*.[[:punct:]]
117 ## BUG ash stdout: _tmp/foo.- _tmp/foo.-
118
119 #### Redirect to glob, not evaluated
120 # This writes to *.F, not foo.F
121 rm _tmp/*.F
122 touch _tmp/f.F
123 echo foo > _tmp/*.F
124 cat '_tmp/*.F'
125 ## status: 0
126 ## stdout: foo
127 ## BUG bash status: 1
128 ## BUG bash stdout-json: ""
129
130 #### Glob after var manipulation
131 touch _tmp/foo.zzz _tmp/bar.zzz
132 g='_tmp/*.zzzZ'
133 echo $g ${g%Z}
134 ## stdout: _tmp/*.zzzZ _tmp/bar.zzz _tmp/foo.zzz
135
136 #### Glob after part joining
137 touch _tmp/foo.yyy _tmp/bar.yyy
138 g='_tmp/*.yy'
139 echo $g ${g}y
140 ## stdout: _tmp/*.yy _tmp/bar.yyy _tmp/foo.yyy
141
142 #### Glob flags on file system
143 touch _tmp/-n _tmp/zzzzz
144 cd _tmp
145 echo -* hello zzzz?
146 ## stdout-json: "hello zzzzz"
147
148 #### set -o noglob
149 cd $REPO_ROOT
150 touch _tmp/spec-tmp/a.zz _tmp/spec-tmp/b.zz
151 echo _tmp/spec-tmp/*.zz
152 set -o noglob
153 echo _tmp/spec-tmp/*.zz
154 ## stdout-json: "_tmp/spec-tmp/a.zz _tmp/spec-tmp/b.zz\n_tmp/spec-tmp/*.zz\n"
155
156 #### set -o noglob (bug #698)
157 var='\z'
158 set -f
159 echo $var
160 ## STDOUT:
161 \z
162 ## END
163
164 #### shopt -s nullglob
165 argv.py _tmp/spec-tmp/*.nonexistent
166 shopt -s nullglob
167 argv.py _tmp/spec-tmp/*.nonexistent
168 ## stdout-json: "['_tmp/spec-tmp/*.nonexistent']\n[]\n"
169 ## N-I dash/mksh/ash stdout-json: "['_tmp/spec-tmp/*.nonexistent']\n['_tmp/spec-tmp/*.nonexistent']\n"
170
171 #### shopt -s failglob in command context
172 argv.py *.ZZ
173 shopt -s failglob
174 argv.py *.ZZ # nothing is printed, not []
175 echo status=$?
176 ## STDOUT:
177 ['*.ZZ']
178 status=1
179 ## END
180 ## N-I dash/mksh/ash STDOUT:
181 ['*.ZZ']
182 ['*.ZZ']
183 status=0
184 ## END
185
186 #### shopt -s failglob in loop context
187 for x in *.ZZ; do echo $x; done
188 echo status=$?
189 shopt -s failglob
190 for x in *.ZZ; do echo $x; done
191 echo status=$?
192 ## STDOUT:
193 *.ZZ
194 status=0
195 status=1
196 ## END
197 ## N-I dash/mksh/ash STDOUT:
198 *.ZZ
199 status=0
200 *.ZZ
201 status=0
202 ## END
203
204 #### Don't glob flags on file system with GLOBIGNORE
205 # This is a bash-specific extension.
206 expr $0 : '.*/osh$' >/dev/null && exit 99 # disabled until cd implemented
207 touch _tmp/-n _tmp/zzzzz
208 cd _tmp # this fail in osh
209 GLOBIGNORE=-*:zzzzz # colon-separated pattern list
210 echo -* hello zzzz?
211 ## stdout-json: "-* hello zzzz?\n"
212 ## N-I dash/mksh/ash stdout-json: "hello zzzzz"
213 ## status: 0
214
215 #### Splitting/Globbing doesn't happen on local assignment
216 cd $REPO_ROOT
217
218 f() {
219 # Dash splits words and globs before handing it to the 'local' builtin. But
220 # ash doesn't!
221 local foo=$1
222 echo "$foo"
223 }
224 f 'void *'
225 ## stdout: void *
226 ## BUG dash stdout-json: ""
227 ## BUG dash status: 2
228
229 #### Glob of unescaped [[] and []]
230 touch $TMP/[ $TMP/]
231 cd $TMP
232 echo [\[z] [\]z] # the right way to do it
233 echo [[z] []z] # also accepted
234 ## STDOUT:
235 [ ]
236 [ ]
237 ## END
238
239 #### Glob of negated unescaped [[] and []]
240 # osh does this "correctly" because it defers to libc!
241 touch $TMP/_G
242 cd $TMP
243 echo _[^\[z] _[^\]z] # the right way to do it
244 echo _[^[z] _[^]z] # also accepted
245 ## STDOUT:
246 _G _G
247 _G _G
248 ## END
249 ## BUG dash/mksh STDOUT:
250 _[^[z] _[^]z]
251 _[^[z] _[^]z]
252 ## END
253
254 #### PatSub of unescaped [[] and []]
255 x='[foo]'
256 echo ${x//[\[z]/<} # the right way to do it
257 echo ${x//[\]z]/>}
258 echo ${x//[[z]/<} # also accepted
259 echo ${x//[]z]/>}
260 ## STDOUT:
261 <foo]
262 [foo>
263 <foo]
264 [foo>
265 ## END
266 ## N-I dash stdout-json: ""
267 ## N-I dash status: 2
268
269 #### PatSub of negated unescaped [[] and []]
270 x='[foo]'
271 echo ${x//[^\[z]/<} # the right way to do it
272 echo ${x//[^\]z]/>}
273 echo ${x//[^[z]/<} # also accepted
274 #echo ${x//[^]z]/>} # only busybox ash interprets as ^\]
275 ## STDOUT:
276 [<<<<
277 >>>>]
278 [<<<<
279 ## END
280 # mksh is doing something very odd, ignoring ^ altogether?
281 ## BUG mksh STDOUT:
282 <foo]
283 [foo>
284 <foo]
285 ## END
286 ## N-I dash stdout-json: ""
287 ## N-I dash status: 2
288
289 #### Glob unicode char
290
291 touch $TMP/__a__
292 touch $TMP/__μ__
293 cd $TMP
294
295 echo __?__
296
297 ## STDOUT:
298 __a__ __μ__
299 ## END
300 ## BUG dash/mksh/ash STDOUT:
301 __a__
302 ## END
303 # note: zsh also passes this, but it doesn't run with this file.
304
305 #### dotglob (bash option that dashglob is roughly consistent with)
306 mkdir -p $TMP/dotglob
307 cd $TMP/dotglob
308 touch .foorc other
309
310 echo *
311 shopt -s dotglob
312 echo *
313 ## STDOUT:
314 other
315 .foorc other
316 ## END
317 ## N-I dash/mksh/ash STDOUT:
318 other
319 other
320 ## END
321