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

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