OILS / spec / glob.test.sh View on Github | oilshell.org

388 lines, 181 significant
1## oils_failures_allowed: 3
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-json: "_tmp/spec-tmp/a.zz _tmp/spec-tmp/b.zz\n_tmp/spec-tmp/*.zz\n"
155
156#### set -o noglob (bug #698)
157var='\z'
158set -f
159echo $var
160## STDOUT:
161\z
162## END
163
164#### shopt -s nullglob
165argv.py _tmp/spec-tmp/*.nonexistent
166shopt -s nullglob
167argv.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
172argv.py *.ZZ
173shopt -s failglob
174argv.py *.ZZ # nothing is printed, not []
175echo status=$?
176## STDOUT:
177['*.ZZ']
178status=1
179## END
180## N-I dash/mksh/ash STDOUT:
181['*.ZZ']
182['*.ZZ']
183status=0
184## END
185
186#### shopt -s failglob in loop context
187for x in *.ZZ; do echo $x; done
188echo status=$?
189shopt -s failglob
190for x in *.ZZ; do echo $x; done
191echo status=$?
192## STDOUT:
193*.ZZ
194status=0
195status=1
196## END
197## N-I dash/mksh/ash STDOUT:
198*.ZZ
199status=0
200*.ZZ
201status=0
202## END
203
204#### shopt -s failglob in array literal context
205myarr=(*.ZZ)
206echo "${myarr[@]}"
207shopt -s failglob
208myarr=(*.ZZ)
209echo status=$?
210## STDOUT:
211*.ZZ
212status=1
213## END
214## N-I mksh STDOUT:
215*.ZZ
216status=0
217## END
218## N-I dash/ash stdout-json: ""
219## N-I dash/ash status: 2
220
221#### shopt -s failglob exits properly in command context with set -e
222set -e
223argv.py *.ZZ
224shopt -s failglob
225argv.py *.ZZ
226echo status=$?
227## STDOUT:
228['*.ZZ']
229## END
230## status: 1
231## N-I dash/mksh/ash STDOUT:
232['*.ZZ']
233## END
234## N-I dash/mksh/ash status: 127
235
236#### shopt -s failglob exits properly in loop context with set -e
237set -e
238for x in *.ZZ; do echo $x; done
239echo status=$?
240
241shopt -s failglob
242for x in *.ZZ; do echo $x; done
243echo status=$?
244
245## status: 1
246## STDOUT:
247*.ZZ
248status=0
249## END
250
251## N-I dash/mksh/ash status: 127
252## N-I dash/mksh/ash STDOUT:
253*.ZZ
254status=0
255## END
256
257#### shopt -s failglob behavior on single line with semicolon
258# bash behaves differently when commands are separated by a semicolon than when
259# separated by a newline. This behavior doesn't make sense or seem to be
260# intentional, so osh does not mimic it.
261
262shopt -s failglob
263echo *.ZZ; echo status=$? # bash doesn't execute the second part!
264echo *.ZZ
265echo status=$? # bash executes this
266
267## STDOUT:
268status=1
269## END
270
271## OK osh STDOUT:
272status=1
273status=1
274## END
275
276## N-I dash/mksh/ash STDOUT:
277*.ZZ
278status=0
279*.ZZ
280status=0
281## END
282
283#### Splitting/Globbing doesn't happen on local assignment
284cd $REPO_ROOT
285
286f() {
287 # Dash splits words and globs before handing it to the 'local' builtin. But
288 # ash doesn't!
289 local foo=$1
290 echo "$foo"
291}
292f 'void *'
293## stdout: void *
294## BUG dash stdout-json: ""
295## BUG dash status: 2
296
297#### Glob of unescaped [[] and []]
298touch $TMP/[ $TMP/]
299cd $TMP
300echo [\[z] [\]z] # the right way to do it
301echo [[z] []z] # also accepted
302## STDOUT:
303[ ]
304[ ]
305## END
306
307#### Glob of negated unescaped [[] and []]
308# osh does this "correctly" because it defers to libc!
309touch $TMP/_G
310cd $TMP
311echo _[^\[z] _[^\]z] # the right way to do it
312echo _[^[z] _[^]z] # also accepted
313## STDOUT:
314_G _G
315_G _G
316## END
317## BUG dash/mksh STDOUT:
318_[^[z] _[^]z]
319_[^[z] _[^]z]
320## END
321
322#### PatSub of unescaped [[] and []]
323x='[foo]'
324echo ${x//[\[z]/<} # the right way to do it
325echo ${x//[\]z]/>}
326echo ${x//[[z]/<} # also accepted
327echo ${x//[]z]/>}
328## STDOUT:
329<foo]
330[foo>
331<foo]
332[foo>
333## END
334## N-I dash stdout-json: ""
335## N-I dash status: 2
336
337#### PatSub of negated unescaped [[] and []]
338x='[foo]'
339echo ${x//[^\[z]/<} # the right way to do it
340echo ${x//[^\]z]/>}
341echo ${x//[^[z]/<} # also accepted
342#echo ${x//[^]z]/>} # only busybox ash interprets as ^\]
343## STDOUT:
344[<<<<
345>>>>]
346[<<<<
347## END
348# mksh is doing something very odd, ignoring ^ altogether?
349## BUG mksh STDOUT:
350<foo]
351[foo>
352<foo]
353## END
354## N-I dash stdout-json: ""
355## N-I dash status: 2
356
357#### Glob unicode char
358
359touch $TMP/__a__
360touch $TMP/__μ__
361cd $TMP
362
363echo __?__
364
365## STDOUT:
366__a__ __μ__
367## END
368## BUG dash/mksh/ash STDOUT:
369__a__
370## END
371# note: zsh also passes this, but it doesn't run with this file.
372
373#### dotglob (bash option that dashglob is roughly consistent with)
374mkdir -p $TMP/dotglob
375cd $TMP/dotglob
376touch .foorc other
377
378echo *
379shopt -s dotglob
380echo *
381## STDOUT:
382other
383.foorc other
384## END
385## N-I dash/mksh/ash STDOUT:
386other
387other
388## END