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

378 lines, 178 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
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=$?
230
231shopt -s failglob
232for x in *.ZZ; do echo $x; done
233echo status=$?
234
235## status: 1
236## STDOUT:
237*.ZZ
238status=0
239## END
240
241## N-I dash/mksh/ash status: 127
242## N-I dash/mksh/ash STDOUT:
243*.ZZ
244status=0
245## END
246
247#### shopt -s failglob behavior on single line with semicolon
248# bash behaves differently when commands are separated by a semicolon than when
249# separated by a newline. This behavior doesn't make sense or seem to be
250# intentional, so osh does not mimic it.
251
252shopt -s failglob
253echo *.ZZ; echo status=$? # bash doesn't execute the second part!
254echo *.ZZ
255echo status=$? # bash executes this
256
257## STDOUT:
258status=1
259## END
260
261## OK osh STDOUT:
262status=1
263status=1
264## END
265
266## N-I dash/mksh/ash STDOUT:
267*.ZZ
268status=0
269*.ZZ
270status=0
271## END
272
273#### Splitting/Globbing doesn't happen on local assignment
274cd $REPO_ROOT
275
276f() {
277 # Dash splits words and globs before handing it to the 'local' builtin. But
278 # ash doesn't!
279 local foo=$1
280 echo "$foo"
281}
282f 'void *'
283## stdout: void *
284## BUG dash stdout-json: ""
285## BUG dash status: 2
286
287#### Glob of unescaped [[] and []]
288touch $TMP/[ $TMP/]
289cd $TMP
290echo [\[z] [\]z] # the right way to do it
291echo [[z] []z] # also accepted
292## STDOUT:
293[ ]
294[ ]
295## END
296
297#### Glob of negated unescaped [[] and []]
298# osh does this "correctly" because it defers to libc!
299touch $TMP/_G
300cd $TMP
301echo _[^\[z] _[^\]z] # the right way to do it
302echo _[^[z] _[^]z] # also accepted
303## STDOUT:
304_G _G
305_G _G
306## END
307## BUG dash/mksh STDOUT:
308_[^[z] _[^]z]
309_[^[z] _[^]z]
310## END
311
312#### PatSub of unescaped [[] and []]
313x='[foo]'
314echo ${x//[\[z]/<} # the right way to do it
315echo ${x//[\]z]/>}
316echo ${x//[[z]/<} # also accepted
317echo ${x//[]z]/>}
318## STDOUT:
319<foo]
320[foo>
321<foo]
322[foo>
323## END
324## N-I dash stdout-json: ""
325## N-I dash status: 2
326
327#### PatSub of negated unescaped [[] and []]
328x='[foo]'
329echo ${x//[^\[z]/<} # the right way to do it
330echo ${x//[^\]z]/>}
331echo ${x//[^[z]/<} # also accepted
332#echo ${x//[^]z]/>} # only busybox ash interprets as ^\]
333## STDOUT:
334[<<<<
335>>>>]
336[<<<<
337## END
338# mksh is doing something very odd, ignoring ^ altogether?
339## BUG mksh STDOUT:
340<foo]
341[foo>
342<foo]
343## END
344## N-I dash stdout-json: ""
345## N-I dash status: 2
346
347#### Glob unicode char
348
349touch $TMP/__a__
350touch $TMP/__μ__
351cd $TMP
352
353echo __?__
354
355## STDOUT:
356__a__ __μ__
357## END
358## BUG dash/mksh/ash STDOUT:
359__a__
360## END
361# note: zsh also passes this, but it doesn't run with this file.
362
363#### dotglob (bash option that dashglob is roughly consistent with)
364mkdir -p $TMP/dotglob
365cd $TMP/dotglob
366touch .foorc other
367
368echo *
369shopt -s dotglob
370echo *
371## STDOUT:
372other
373.foorc other
374## END
375## N-I dash/mksh/ash STDOUT:
376other
377other
378## END