OILS / spec / glob.test.sh View on Github | oils.pub

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