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

375 lines, 178 significant
1#
2# NOTE: Could move spec/03-glob.sh here.
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
114touch _tmp/foo.-
115echo _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
121touch _tmp/foo.zzz _tmp/bar.zzz
122g='_tmp/*.zzzZ'
123echo $g ${g%Z}
124## stdout: _tmp/*.zzzZ _tmp/bar.zzz _tmp/foo.zzz
125
126#### Glob after part joining
127touch _tmp/foo.yyy _tmp/bar.yyy
128g='_tmp/*.yy'
129echo $g ${g}y
130## stdout: _tmp/*.yy _tmp/bar.yyy _tmp/foo.yyy
131
132#### Glob flags on file system
133touch _tmp/-n _tmp/zzzzz
134cd _tmp
135echo -* hello zzzz?
136## stdout-json: "hello zzzzz"
137
138#### set -o noglob
139cd $REPO_ROOT
140touch _tmp/spec-tmp/a.zz _tmp/spec-tmp/b.zz
141echo _tmp/spec-tmp/*.zz
142set -o noglob
143echo _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)
147var='\z'
148set -f
149echo $var
150## STDOUT:
151\z
152## END
153
154#### shopt -s nullglob
155argv.py _tmp/spec-tmp/*.nonexistent
156shopt -s nullglob
157argv.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
162argv.py *.ZZ
163shopt -s failglob
164argv.py *.ZZ # nothing is printed, not []
165echo status=$?
166## STDOUT:
167['*.ZZ']
168status=1
169## END
170## N-I dash/mksh/ash STDOUT:
171['*.ZZ']
172['*.ZZ']
173status=0
174## END
175
176#### shopt -s failglob in loop context
177for x in *.ZZ; do echo $x; done
178echo status=$?
179shopt -s failglob
180for x in *.ZZ; do echo $x; done
181echo status=$?
182## STDOUT:
183*.ZZ
184status=0
185status=1
186## END
187## N-I dash/mksh/ash STDOUT:
188*.ZZ
189status=0
190*.ZZ
191status=0
192## END
193
194#### shopt -s failglob in array literal context
195myarr=(*.ZZ)
196echo "${myarr[@]}"
197shopt -s failglob
198myarr=(*.ZZ)
199echo status=$?
200## STDOUT:
201*.ZZ
202status=1
203## END
204## N-I mksh STDOUT:
205*.ZZ
206status=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
212set -e
213argv.py *.ZZ
214shopt -s failglob
215argv.py *.ZZ
216echo 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
227set -e
228for x in *.ZZ; do echo $x; done
229echo status=$?
230shopt -s failglob
231for x in *.ZZ; do echo $x; done
232echo status=$?
233## STDOUT:
234*.ZZ
235status=0
236## END
237## status: 1
238## N-I dash/mksh/ash STDOUT:
239*.ZZ
240status=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
249shopt -s failglob
250echo *.ZZ; echo status=$? # bash doesn't execute the second part!
251echo *.ZZ
252echo status=$? # bash executes this
253
254## STDOUT:
255status=1
256## END
257
258## OK osh STDOUT:
259status=1
260status=1
261## END
262
263## N-I dash/mksh/ash STDOUT:
264*.ZZ
265status=0
266*.ZZ
267status=0
268## END
269
270#### Splitting/Globbing doesn't happen on local assignment
271cd $REPO_ROOT
272
273f() {
274 # Dash splits words and globs before handing it to the 'local' builtin. But
275 # ash doesn't!
276 local foo=$1
277 echo "$foo"
278}
279f 'void *'
280## stdout: void *
281## BUG dash stdout-json: ""
282## BUG dash status: 2
283
284#### Glob of unescaped [[] and []]
285touch $TMP/[ $TMP/]
286cd $TMP
287echo [\[z] [\]z] # the right way to do it
288echo [[z] []z] # also accepted
289## STDOUT:
290[ ]
291[ ]
292## END
293
294#### Glob of negated unescaped [[] and []]
295# osh does this "correctly" because it defers to libc!
296touch $TMP/_G
297cd $TMP
298echo _[^\[z] _[^\]z] # the right way to do it
299echo _[^[z] _[^]z] # also accepted
300## STDOUT:
301_G _G
302_G _G
303## END
304## BUG dash/mksh STDOUT:
305_[^[z] _[^]z]
306_[^[z] _[^]z]
307## END
308
309#### PatSub of unescaped [[] and []]
310x='[foo]'
311echo ${x//[\[z]/<} # the right way to do it
312echo ${x//[\]z]/>}
313echo ${x//[[z]/<} # also accepted
314echo ${x//[]z]/>}
315## STDOUT:
316<foo]
317[foo>
318<foo]
319[foo>
320## END
321## N-I dash stdout-json: ""
322## N-I dash status: 2
323
324#### PatSub of negated unescaped [[] and []]
325x='[foo]'
326echo ${x//[^\[z]/<} # the right way to do it
327echo ${x//[^\]z]/>}
328echo ${x//[^[z]/<} # also accepted
329#echo ${x//[^]z]/>} # only busybox ash interprets as ^\]
330## STDOUT:
331[<<<<
332>>>>]
333[<<<<
334## END
335# mksh is doing something very odd, ignoring ^ altogether?
336## BUG mksh STDOUT:
337<foo]
338[foo>
339<foo]
340## END
341## N-I dash stdout-json: ""
342## N-I dash status: 2
343
344#### Glob unicode char
345
346touch $TMP/__a__
347touch $TMP/__μ__
348cd $TMP
349
350echo __?__
351
352## STDOUT:
353__a__ __μ__
354## END
355## BUG dash/mksh/ash STDOUT:
356__a__
357## END
358# note: zsh also passes this, but it doesn't run with this file.
359
360#### dotglob (bash option that dashglob is roughly consistent with)
361mkdir -p $TMP/dotglob
362cd $TMP/dotglob
363touch .foorc other
364
365echo *
366shopt -s dotglob
367echo *
368## STDOUT:
369other
370.foorc other
371## END
372## N-I dash/mksh/ash STDOUT:
373other
374other
375## END