xref: /titanic_50/usr/src/lib/libshell/common/tests/bracket.sh (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4*3e14f97fSRoger A. Faulkner#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6da2e3ebdSchin#                  Common Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10da2e3ebdSchin#            http://www.opensource.org/licenses/cpl1.0.txt             #
11da2e3ebdSchin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12da2e3ebdSchin#                                                                      #
13da2e3ebdSchin#              Information and Software Systems Research               #
14da2e3ebdSchin#                            AT&T Research                             #
15da2e3ebdSchin#                           Florham Park NJ                            #
16da2e3ebdSchin#                                                                      #
17da2e3ebdSchin#                  David Korn <dgk@research.att.com>                   #
18da2e3ebdSchin#                                                                      #
19da2e3ebdSchin########################################################################
20da2e3ebdSchinfunction err_exit
21da2e3ebdSchin{
22da2e3ebdSchin	print -u2 -n "\t"
23da2e3ebdSchin	print -u2 -r ${Command}[$1]: "${@:2}"
24da2e3ebdSchin	let Errors+=1
25da2e3ebdSchin}
26da2e3ebdSchinalias err_exit='err_exit $LINENO'
27da2e3ebdSchin
28da2e3ebdSchinCommand=${0##*/}
29da2e3ebdSchininteger Errors=0
3034f9b3eeSRoland Mainz
3134f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3234f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT
3334f9b3eeSRoland Mainz
34da2e3ebdSchinnull=''
35da2e3ebdSchinif	[[ ! -z $null ]]
36da2e3ebdSchinthen	err_exit "-z: null string should be of zero length"
37da2e3ebdSchinfi
3834f9b3eeSRoland Mainzfile=$tmp/original
3934f9b3eeSRoland Mainznewer_file=$tmp/newer
40da2e3ebdSchinif	[[ -z $file ]]
41da2e3ebdSchinthen	err_exit "-z: $file string should not be of zero length"
42da2e3ebdSchinfi
43da2e3ebdSchinif	[[ -a $file ]]
44da2e3ebdSchinthen	err_exit "-a: $file shouldn't exist"
45da2e3ebdSchinfi
46da2e3ebdSchin> $file
47da2e3ebdSchinif	[[ ! -a $file ]]
48da2e3ebdSchinthen	err_exit "-a: $file should exist"
49da2e3ebdSchinfi
50da2e3ebdSchinchmod 777 $file
51da2e3ebdSchinif	[[ ! -r $file ]]
52da2e3ebdSchinthen	err_exit "-r: $file should be readable"
53da2e3ebdSchinfi
54da2e3ebdSchinif	[[ ! -w $file ]]
55da2e3ebdSchinthen	err_exit "-w: $file should be writable"
56da2e3ebdSchinfi
57da2e3ebdSchinif	[[ ! -w $file ]]
58da2e3ebdSchinthen	err_exit "-x: $file should be executable"
59da2e3ebdSchinfi
60da2e3ebdSchinif	[[ ! -w $file || ! -r $file ]]
61da2e3ebdSchinthen	err_exit "-rw: $file should be readable/writable"
62da2e3ebdSchinfi
63da2e3ebdSchinif	[[ -s $file ]]
64da2e3ebdSchinthen	err_exit "-s: $file should be of zero size"
65da2e3ebdSchinfi
66da2e3ebdSchinif	[[ ! -f $file ]]
67da2e3ebdSchinthen	err_exit "-f: $file should be an ordinary file"
68da2e3ebdSchinfi
69da2e3ebdSchinif	[[  -d $file ]]
70da2e3ebdSchinthen	err_exit "-f: $file should not be a directory file"
71da2e3ebdSchinfi
72da2e3ebdSchinif	[[  ! -d . ]]
73da2e3ebdSchinthen	err_exit "-d: . should not be a directory file"
74da2e3ebdSchinfi
75da2e3ebdSchinif	[[  -f /dev/null ]]
76da2e3ebdSchinthen	err_exit "-f: /dev/null  should not be an ordinary file"
77da2e3ebdSchinfi
78da2e3ebdSchinchmod 000 $file
79da2e3ebdSchinif	[[ -r $file ]]
80da2e3ebdSchinthen	err_exit "-r: $file should not be readable"
81da2e3ebdSchinfi
82da2e3ebdSchinif	[[ ! -O $file ]]
83da2e3ebdSchinthen	err_exit "-r: $file should be owned by me"
84da2e3ebdSchinfi
85da2e3ebdSchinif	[[ -w $file ]]
86da2e3ebdSchinthen	err_exit "-w: $file should not be writable"
87da2e3ebdSchinfi
88da2e3ebdSchinif	[[ -w $file ]]
89da2e3ebdSchinthen	err_exit "-x: $file should not be executable"
90da2e3ebdSchinfi
91da2e3ebdSchinif	[[ -w $file || -r $file ]]
92da2e3ebdSchinthen	err_exit "-rw: $file should not be readable/writable"
93da2e3ebdSchinfi
94da2e3ebdSchinif	[[   -z x &&  -z x || ! -z x ]]
95da2e3ebdSchinthen	:
96da2e3ebdSchinelse	err_exit " wrong precedence"
97da2e3ebdSchinfi
98da2e3ebdSchinif	[[   -z x &&  (-z x || ! -z x) ]]
99da2e3ebdSchinthen	err_exit " () grouping not working"
100da2e3ebdSchinfi
101da2e3ebdSchinif	[[ foo < bar ]]
102da2e3ebdSchinthen	err_exit "foo comes before bar"
103da2e3ebdSchinfi
104da2e3ebdSchin[[ . -ef $(pwd) ]] || err_exit ". is not $PWD"
105da2e3ebdSchinset -o allexport
106da2e3ebdSchin[[ -o allexport ]] || err_exit '-o: did not set allexport option'
107da2e3ebdSchinif	[[ -n  $null ]]
108da2e3ebdSchinthen	err_exit "'$null' has non-zero length"
109da2e3ebdSchinfi
110da2e3ebdSchinif	[[ ! -r /dev/fd/0 ]]
111da2e3ebdSchinthen	err_exit "/dev/fd/0 not open for reading"
112da2e3ebdSchinfi
113da2e3ebdSchinif	[[ ! -w /dev/fd/2 ]]
114da2e3ebdSchinthen	err_exit "/dev/fd/2 not open for writing"
115da2e3ebdSchinfi
116da2e3ebdSchinsleep 1
1177c2fbfb3SApril Chin> $newer_file
1187c2fbfb3SApril Chinif	[[ ! $file -ot $newer_file ]]
1197c2fbfb3SApril Chinthen	err_exit "$file should be older than $newer_file"
120da2e3ebdSchinfi
1217c2fbfb3SApril Chinif	[[ $file -nt $newer_file ]]
1227c2fbfb3SApril Chinthen	err_exit "$newer_file should be newer than $file"
123da2e3ebdSchinfi
12434f9b3eeSRoland Mainzif	[[ $file != $tmp/* ]]
12534f9b3eeSRoland Mainzthen	err_exit "$file should match $tmp/*"
126da2e3ebdSchinfi
12734f9b3eeSRoland Mainzif	[[ $file = $tmp'/*' ]]
12834f9b3eeSRoland Mainzthen	err_exit "$file should not equal $tmp'/*'"
129da2e3ebdSchinfi
130da2e3ebdSchin[[ ! ( ! -z $null && ! -z x) ]]	|| err_exit "negation and grouping"
131da2e3ebdSchin[[ -z '' || -z '' || -z '' ]]	|| err_exit "three ors not working"
132da2e3ebdSchin[[ -z '' &&  -z '' && -z '' ]]	|| err_exit "three ors not working"
133da2e3ebdSchin(exit 8)
134da2e3ebdSchinif	[[ $? -ne 8 || $? -ne 8 ]]
135da2e3ebdSchinthen	err_exit 'value $? within [[...]]'
136da2e3ebdSchinfi
137da2e3ebdSchinx='(x'
138da2e3ebdSchinif	[[ '(x' != '('* ]]
139da2e3ebdSchinthen	err_exit " '(x' does not match '('* within [[...]]"
140da2e3ebdSchinfi
141da2e3ebdSchinif	[[ '(x' != "("* ]]
142da2e3ebdSchinthen	err_exit ' "(x" does not match "("* within [[...]]'
143da2e3ebdSchinfi
144da2e3ebdSchinif	[[ '(x' != \(* ]]
145da2e3ebdSchinthen	err_exit ' "(x" does not match \(* within [[...]]'
146da2e3ebdSchinfi
147da2e3ebdSchinif	[[ 'x(' != *'(' ]]
148da2e3ebdSchinthen	err_exit " 'x(' does not match '('* within [[...]]"
149da2e3ebdSchinfi
150da2e3ebdSchinif	[[ 'x&' != *'&' ]]
151da2e3ebdSchinthen	err_exit " 'x&' does not match '&'* within [[...]]"
152da2e3ebdSchinfi
153da2e3ebdSchinif	[[ 'xy' = *'*' ]]
154da2e3ebdSchinthen	err_exit " 'xy' matches *'*' within [[...]]"
155da2e3ebdSchinfi
156da2e3ebdSchinif	[[ 3 > 4 ]]
157da2e3ebdSchinthen	err_exit '3 < 4'
158da2e3ebdSchinfi
159da2e3ebdSchinif	[[ 4 < 3 ]]
160da2e3ebdSchinthen	err_exit '3 > 4'
161da2e3ebdSchinfi
162da2e3ebdSchinif	[[ 3x > 4x ]]
163da2e3ebdSchinthen	err_exit '3x < 4x'
164da2e3ebdSchinfi
165da2e3ebdSchinx='bin|dev|?'
166da2e3ebdSchincd /
167da2e3ebdSchinif	[[ $(print $x) != "$x" ]]
168da2e3ebdSchinthen	err_exit 'extended pattern matching on command arguments'
169da2e3ebdSchinfi
170da2e3ebdSchinif	[[ dev != $x ]]
171da2e3ebdSchinthen	err_exit 'extended pattern matching not working on variables'
172da2e3ebdSchinfi
173da2e3ebdSchinif	[[ -u $SHELL ]]
174da2e3ebdSchinthen	err_exit "setuid on $SHELL"
175da2e3ebdSchinfi
176da2e3ebdSchinif	[[ -g $SHELL ]]
177da2e3ebdSchinthen	err_exit "setgid on $SHELL"
178da2e3ebdSchinfi
179da2e3ebdSchintest -d .  -a '(' ! -f . ')' || err_exit 'test not working'
180da2e3ebdSchinif	[[ '!' != ! ]]
181da2e3ebdSchinthen	err_exit 'quoting unary operator not working'
182da2e3ebdSchinfi
1837c2fbfb3SApril Chintest \( -n x \) -o \( -n y \) 2> /dev/null || err_exit 'test ( -n x ) -o ( -n y) not working'
1847c2fbfb3SApril Chintest \( -n x \) -o -n y 2> /dev/null || err_exit 'test ( -n x ) -o -n y not working'
185da2e3ebdSchinchmod 600 $file
186da2e3ebdSchinexec 4> $file
187da2e3ebdSchinprint -u4 foobar
188da2e3ebdSchinif	[[ ! -s $file ]]
189da2e3ebdSchinthen	err_exit "-s: $file should be non-zero"
190da2e3ebdSchinfi
191da2e3ebdSchinexec 4>&-
192da2e3ebdSchinif	[[ 011 -ne 11 ]]
193da2e3ebdSchinthen	err_exit "leading zeros in arithmetic compares not ignored"
194da2e3ebdSchinfi
195da2e3ebdSchin{
196da2e3ebdSchin	set -x
197da2e3ebdSchin	[[ foo > bar ]]
198da2e3ebdSchin} 2> /dev/null || { set +x; err_exit "foo<bar with -x enabled" ;}
199da2e3ebdSchinset +x
200da2e3ebdSchin(
201da2e3ebdSchin	eval "[[ (a) ]]"
202da2e3ebdSchin) 2> /dev/null || err_exit "[[ (a) ]] not working"
203da2e3ebdSchin> $file
204da2e3ebdSchinchmod 4755 "$file"
205da2e3ebdSchinif	test -u $file && test ! -u $file
206da2e3ebdSchinthen	err_exit "test ! -u suidfile not working"
207da2e3ebdSchinfi
208da2e3ebdSchinfor i in '(' ')' '[' ']'
209da2e3ebdSchindo	[[ $i == $i ]] || err_exit "[[ $i != $i ]]"
210da2e3ebdSchindone
211da2e3ebdSchin(
212da2e3ebdSchin	[[ aaaa == {4}(a) ]] || err_exit 'aaaa != {4}(a)'
213da2e3ebdSchin	[[ aaaa == {2,5}(a) ]] || err_exit 'aaaa != {2,4}(a)'
214da2e3ebdSchin	[[ abcdcdabcd == {3,6}(ab|cd) ]] || err_exit 'abcdcdabcd == {3,4}(ab|cd)'
215da2e3ebdSchin	[[ abcdcdabcde == {5}(ab|cd)e ]] || err_exit 'abcdcdabcd == {5}(ab|cd)e'
21634f9b3eeSRoland Mainz) || err_exit 'errors with {..}(...) patterns'
217da2e3ebdSchin[[ D290.2003.02.16.temp == D290.+(2003.02.16).temp* ]] || err_exit 'pattern match bug with +(...)'
218da2e3ebdSchinrm -rf $file
219da2e3ebdSchin{
22034f9b3eeSRoland Mainz[[ -N $file ]] && err_exit 'test -N $tmp/*: st_mtime>st_atime after creat'
221da2e3ebdSchinsleep 2
222da2e3ebdSchinprint 'hello world'
22334f9b3eeSRoland Mainz[[ -N $file ]] || err_exit 'test -N $tmp/*: st_mtime<=st_atime after write'
224da2e3ebdSchinsleep 2
225da2e3ebdSchinread
22634f9b3eeSRoland Mainz[[ -N $file ]] && err_exit 'test -N $tmp/*: st_mtime>st_atime after read'
227da2e3ebdSchin} > $file < $file
228da2e3ebdSchinif	rm -rf "$file" && ln -s / "$file"
229da2e3ebdSchinthen	[[ -L "$file" ]] || err_exit '-L not working'
230da2e3ebdSchin	[[ -L "$file"/ ]] && err_exit '-L with file/ not working'
231da2e3ebdSchinfi
232da2e3ebdSchin$SHELL -c 't=1234567890; [[ $t == @({10}(\d)) ]]' 2> /dev/null || err_exit ' @({10}(\d)) pattern not working'
233da2e3ebdSchin$SHELL -c '[[ att_ == ~(E)(att|cus)_.* ]]' 2> /dev/null || err_exit ' ~(E)(att|cus)_* pattern not working'
234da2e3ebdSchin$SHELL -c '[[ att_ =~ (att|cus)_.* ]]' 2> /dev/null || err_exit ' =~ ere not working'
235da2e3ebdSchin$SHELL -c '[[ abc =~ a(b)c ]]' 2> /dev/null || err_exit '[[ abc =~ a(b)c ]] fails'
236da2e3ebdSchin$SHELL -xc '[[ abc =~  \babc\b ]]' 2> /dev/null || err_exit '[[ abc =~ \babc\b ]] fails'
237da2e3ebdSchin[[ abc == ~(E)\babc\b ]] || err_exit '\b not preserved for ere when not in ()'
238da2e3ebdSchin[[ abc == ~(iEi)\babc\b ]] || err_exit '\b not preserved for ~(iEi) when not in ()'
2397c2fbfb3SApril Chin
2407c2fbfb3SApril Chine=$($SHELL -c '[ -z "" -a -z "" ]' 2>&1)
2417c2fbfb3SApril Chin[[ $e ]] && err_exit "[ ... ] compatibility check failed -- $e"
2427c2fbfb3SApril Chini=hell
2437c2fbfb3SApril Chin[[ hell0 == $i[0] ]]  ||  err_exit 'pattern $i[0] interpreded as array ref'
2447c2fbfb3SApril Chintest '(' = ')' && err_exit '"test ( = )" should not be true'
2457c2fbfb3SApril Chin[[ $($SHELL -c 'case  F in ~(Eilr)[a-z0-9#]) print ok;;esac' 2> /dev/null) == ok ]] || err_exit '~(Eilr) not working in case command'
2467c2fbfb3SApril Chin[[ $($SHELL -c "case  Q in ~(Fi)q |  \$'\E') print ok;;esac" 2> /dev/null) == ok ]] || err_exit '~(Fi)q | \E  not working in case command'
24734f9b3eeSRoland Mainz
24834f9b3eeSRoland Mainzfor l in C en_US.ISO8859-15
24934f9b3eeSRoland Mainzdo	[[ $($SHELL -c "LC_COLLATE=$l" 2>&1) ]] && continue
25034f9b3eeSRoland Mainz	export LC_COLLATE=$l
25134f9b3eeSRoland Mainz	set -- \
25234f9b3eeSRoland Mainz		'A'   0 1 1   0 1 1      1 0 0   1 0 0   \
25334f9b3eeSRoland Mainz		'Z'   0 1 1   0 1 1      1 0 0   1 0 0   \
25434f9b3eeSRoland Mainz		'/'   0 0 0   0 0 0      1 1 1   1 1 1   \
25534f9b3eeSRoland Mainz		'.'   0 0 0   0 0 0      1 1 1   1 1 1   \
25634f9b3eeSRoland Mainz		'_'   0 0 0   0 0 0      1 1 1   1 1 1   \
25734f9b3eeSRoland Mainz		'-'   1 1 1   1 1 1      0 0 0   0 0 0   \
25834f9b3eeSRoland Mainz		'%'   0 0 0   0 0 0      1 1 1   1 1 1   \
25934f9b3eeSRoland Mainz		'@'   0 0 0   0 0 0      1 1 1   1 1 1   \
26034f9b3eeSRoland Mainz		'!'   0 0 0   0 0 0      1 1 1   1 1 1   \
26134f9b3eeSRoland Mainz		'^'   0 0 0   0 0 0      1 1 1   1 1 1   \
26234f9b3eeSRoland Mainz		# retain this line #
26334f9b3eeSRoland Mainz	while	(( $# >= 13 ))
26434f9b3eeSRoland Mainz	do	c=$1
26534f9b3eeSRoland Mainz		shift
26634f9b3eeSRoland Mainz		for p in \
26734f9b3eeSRoland Mainz			'[![.-.]]' \
26834f9b3eeSRoland Mainz			'[![.-.][:upper:]]' \
26934f9b3eeSRoland Mainz			'[![.-.]A-Z]' \
27034f9b3eeSRoland Mainz			'[!-]' \
27134f9b3eeSRoland Mainz			'[!-[:upper:]]' \
27234f9b3eeSRoland Mainz			'[!-A-Z]' \
27334f9b3eeSRoland Mainz			'[[.-.]]' \
27434f9b3eeSRoland Mainz			'[[.-.][:upper:]]' \
27534f9b3eeSRoland Mainz			'[[.-.]A-Z]' \
27634f9b3eeSRoland Mainz			'[-]' \
27734f9b3eeSRoland Mainz			'[-[:upper:]]' \
27834f9b3eeSRoland Mainz			'[-A-Z]' \
27934f9b3eeSRoland Mainz			# retain this line #
28034f9b3eeSRoland Mainz		do	e=$1
28134f9b3eeSRoland Mainz			shift
28234f9b3eeSRoland Mainz			[[ $c == $p ]]
28334f9b3eeSRoland Mainz			g=$?
28434f9b3eeSRoland Mainz			[[ $g == $e ]] || err_exit "[[ '$c' == $p ]] for LC_COLLATE=$l failed -- expected $e, got $g"
28534f9b3eeSRoland Mainz		done
28634f9b3eeSRoland Mainz	done
28734f9b3eeSRoland Mainzdone
28834f9b3eeSRoland Mainzinteger n
28934f9b3eeSRoland Mainzif	( : < /dev/tty ) 2>/dev/null && exec {n}< /dev/tty
29034f9b3eeSRoland Mainzthen	[[ -t  $n ]] || err_exit "[[ -t  n ]] fails when n > 9"
29134f9b3eeSRoland Mainzfi
29234f9b3eeSRoland Mainzfoo=([1]=a [2]=b [3]=c)
29334f9b3eeSRoland Mainz[[ -v foo[1] ]] ||  err_exit 'foo[1] should be set'
29434f9b3eeSRoland Mainz[[ ${foo[1]+x} ]] ||  err_exit '${foo[1]+x} should be x'
29534f9b3eeSRoland Mainz[[ ${foo[@]+x} ]] ||  err_exit '${foo[@]+x} should be x'
29634f9b3eeSRoland Mainzunset foo[1]
29734f9b3eeSRoland Mainz[[ -v foo[1] ]] && err_exit 'foo[1] should not be set'
29834f9b3eeSRoland Mainz[[ ${foo[1]+x} ]] &&  err_exit '${foo[1]+x} should be empty'
29934f9b3eeSRoland Mainzbar=(a b c)
30034f9b3eeSRoland Mainz[[ -v bar[1] ]]  || err_exit 'bar[1] should be set'
30134f9b3eeSRoland Mainz[[ ${bar[1]+x} ]] ||  err_exit '${foo[1]+x} should be x'
30234f9b3eeSRoland Mainzunset bar[1]
30334f9b3eeSRoland Mainz[[ ${bar[1]+x} ]] &&  err_exit '${foo[1]+x} should be empty'
30434f9b3eeSRoland Mainz[[ -v bar ]] || err_exit 'bar should be set'
30534f9b3eeSRoland Mainz[[ -v bar[1] ]] && err_exit 'bar[1] should not be set'
30634f9b3eeSRoland Mainzinteger z=( 1 2 4)
30734f9b3eeSRoland Mainz[[ -v z[1] ]] || err_exit 'z[1] should be set'
30834f9b3eeSRoland Mainzunset z[1]
30934f9b3eeSRoland Mainz[[ -v z[1] ]] && err_exit 'z[1] should not be set'
31034f9b3eeSRoland Mainztypeset -si y=( 1 2 4)
31134f9b3eeSRoland Mainz[[ -v y[6] ]] && err_exit 'y[6] should not be set'
31234f9b3eeSRoland Mainz[[ -v y[1] ]] ||  err_exit  'y[1] should be set'
31334f9b3eeSRoland Mainzunset y[1]
31434f9b3eeSRoland Mainz[[ -v y[1] ]] && err_exit 'y[1] should not be set'
31534f9b3eeSRoland Mainzx=abc
31634f9b3eeSRoland Mainz[[ -v x[0] ]] || err_exit  'x[0] should be set'
31734f9b3eeSRoland Mainz[[ ${x[0]+x} ]] || err_exit print  '${x[0]+x} should be x'
31834f9b3eeSRoland Mainz[[ -v x[3] ]] && err_exit 'x[3] should not be set'
31934f9b3eeSRoland Mainz[[ ${x[3]+x} ]] && err_exit  '${x[0]+x} should be Empty'
32034f9b3eeSRoland Mainzunset x
32134f9b3eeSRoland Mainz[[ ${x[@]+x} ]] && err_exit  '${x[@]+x} should be Empty'
32234f9b3eeSRoland Mainzunset x y z foo bar
323da2e3ebdSchinexit $((Errors))
324