1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4b30d1939SAndy Fiddaman#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6b30d1939SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10b30d1939SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
11b30d1939SAndy Fiddaman#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
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
3434f9b3eeSRoland Mainz# test shell builtin commands
35da2e3ebdSchinbuiltin getconf
36da2e3ebdSchin: ${foo=bar} || err_exit ": failed"
37b30d1939SAndy Fiddaman[[ $foo == bar ]] || err_exit ": side effects failed"
38da2e3ebdSchinset -- - foobar
39b30d1939SAndy Fiddaman[[ $# == 2 && $1 == - && $2 == foobar ]] || err_exit "set -- - foobar failed"
40da2e3ebdSchinset -- -x foobar
41b30d1939SAndy Fiddaman[[ $# == 2 && $1 == -x && $2 == foobar ]] || err_exit "set -- -x foobar failed"
42da2e3ebdSchingetopts :x: foo || err_exit "getopts :x: returns false"
43b30d1939SAndy Fiddaman[[ $foo == x && $OPTARG == foobar ]] || err_exit "getopts :x: failed"
44da2e3ebdSchinOPTIND=1
45da2e3ebdSchingetopts :r:s var -r
46da2e3ebdSchinif	[[ $var != : || $OPTARG != r ]]
47da2e3ebdSchinthen	err_exit "'getopts :r:s var -r' not working"
48da2e3ebdSchinfi
49da2e3ebdSchinOPTIND=1
507c2fbfb3SApril Chingetopts :d#u OPT -d 16177
517c2fbfb3SApril Chinif	[[ $OPT != d || $OPTARG != 16177 ]]
527c2fbfb3SApril Chinthen	err_exit "'getopts :d#u OPT=d OPTARG=16177' failed -- OPT=$OPT OPTARG=$OPTARG"
53da2e3ebdSchinfi
54da2e3ebdSchinOPTIND=1
55da2e3ebdSchinwhile getopts 'ab' option -a -b
56da2e3ebdSchindo	[[ $OPTIND == $((OPTIND)) ]] || err_exit "OPTIND optimization bug"
57da2e3ebdSchindone
58da2e3ebdSchin
59da2e3ebdSchinUSAGE=$'[-][S:server?Operate on the specified \asubservice\a:]:[subservice:=pmserver]
60da2e3ebdSchin    {
61da2e3ebdSchin        [p:pmserver]
62da2e3ebdSchin        [r:repserver]
63da2e3ebdSchin        [11:notifyd]
64da2e3ebdSchin    }'
65da2e3ebdSchinset pmser p rep r notifyd -11
66da2e3ebdSchinwhile	(( $# > 1 ))
67da2e3ebdSchindo	OPTIND=1
68da2e3ebdSchin	getopts "$USAGE" OPT -S $1
69da2e3ebdSchin	[[ $OPT == S && $OPTARG == $2 ]] || err_exit "OPT=$OPT OPTARG=$OPTARG -- expected OPT=S OPTARG=$2"
70da2e3ebdSchin	shift 2
71da2e3ebdSchindone
72da2e3ebdSchin
73da2e3ebdSchinfalse ${foo=bar} &&  err_exit "false failed"
74da2e3ebdSchinread <<!
75da2e3ebdSchinhello world
76da2e3ebdSchin!
77b30d1939SAndy Fiddaman[[ $REPLY == 'hello world' ]] || err_exit "read builtin failed"
78da2e3ebdSchinprint x:y | IFS=: read a b
79da2e3ebdSchinif	[[ $a != x ]]
80da2e3ebdSchinthen	err_exit "IFS=: read ... not working"
81da2e3ebdSchinfi
82da2e3ebdSchinread <<!
83da2e3ebdSchinhello \
84da2e3ebdSchinworld
85da2e3ebdSchin!
86b30d1939SAndy Fiddaman[[ $REPLY == 'hello world' ]] || err_exit "read continuation failed"
87da2e3ebdSchinread -d x <<!
88da2e3ebdSchinhello worldxfoobar
89da2e3ebdSchin!
90b30d1939SAndy Fiddaman[[ $REPLY == 'hello world' ]] || err_exit "read builtin failed"
91da2e3ebdSchinread <<\!
92da2e3ebdSchinhello \
93da2e3ebdSchin	world \
94da2e3ebdSchin
95da2e3ebdSchin!
96da2e3ebdSchin[[ $REPLY == 'hello 	world' ]] || err_exit "read continuation2 failed"
97da2e3ebdSchinprint "one\ntwo" | { read line
98da2e3ebdSchin	print $line | /bin/cat > /dev/null
99da2e3ebdSchin	read line
100da2e3ebdSchin}
101da2e3ebdSchinread <<\!
102da2e3ebdSchin\
103da2e3ebdSchina\
104da2e3ebdSchin\
105da2e3ebdSchin\
106da2e3ebdSchinb
107da2e3ebdSchin!
108da2e3ebdSchinif	[[ $REPLY != ab ]]
109da2e3ebdSchinthen	err_exit "read multiple continuation failed"
110da2e3ebdSchinfi
111da2e3ebdSchinif	[[ $line != two ]]
112da2e3ebdSchinthen	err_exit "read from pipeline failed"
113da2e3ebdSchinfi
114da2e3ebdSchinline=two
115da2e3ebdSchinread line < /dev/null
116da2e3ebdSchinif	[[ $line != "" ]]
117da2e3ebdSchinthen	err_exit "read from /dev/null failed"
118da2e3ebdSchinfi
119da2e3ebdSchinif	[[ $(print -R -) != - ]]
120da2e3ebdSchinthen	err_exit "print -R not working correctly"
121da2e3ebdSchinfi
122da2e3ebdSchinif	[[ $(print -- -) != - ]]
123da2e3ebdSchinthen	err_exit "print -- not working correctly"
124da2e3ebdSchinfi
125da2e3ebdSchinprint -f "hello%nbar\n" size > /dev/null
126da2e3ebdSchinif	((	size != 5 ))
127da2e3ebdSchinthen	err_exit "%n format of printf not working"
128da2e3ebdSchinfi
129da2e3ebdSchinprint -n -u2 2>&1-
130da2e3ebdSchin[[ -w /dev/fd/1 ]] || err_exit "2<&1- with built-ins has side effects"
131da2e3ebdSchinx=$0
132da2e3ebdSchinif	[[ $(eval 'print $0') != $x ]]
133da2e3ebdSchinthen	err_exit '$0 not correct for eval'
134da2e3ebdSchinfi
1357c2fbfb3SApril Chin$SHELL -c 'read x <<< hello' 2> /dev/null || err_exit 'syntax <<< not recognized'
1367c2fbfb3SApril Chin($SHELL -c 'read x[1] <<< hello') 2> /dev/null || err_exit 'read x[1] not working'
137da2e3ebdSchinunset x
138da2e3ebdSchinreadonly x
139da2e3ebdSchinset -- $(readonly)
140da2e3ebdSchinif      [[ " $@ " != *" x "* ]]
141da2e3ebdSchinthen    err_exit 'unset readonly variables are not displayed'
142da2e3ebdSchinfi
143da2e3ebdSchinif	[[ $(	for i in foo bar
144da2e3ebdSchin		do	print $i
145da2e3ebdSchin			continue 10
146da2e3ebdSchin		done
147da2e3ebdSchin	    ) != $'foo\nbar' ]]
148da2e3ebdSchinthen	err_exit 'continue breaks out of loop'
149da2e3ebdSchinfi
150da2e3ebdSchin(continue bad 2>/dev/null && err_exit 'continue bad should return an error')
151da2e3ebdSchin(break bad 2>/dev/null && err_exit 'break bad should return an error')
152da2e3ebdSchin(continue 0 2>/dev/null && err_exit 'continue 0 should return an error')
153da2e3ebdSchin(break 0 2>/dev/null && err_exit 'break 0 should return an error')
154da2e3ebdSchinbreakfun() { break;}
155da2e3ebdSchincontinuefun() { continue;}
156da2e3ebdSchinfor fun in break continue
157da2e3ebdSchindo	if	[[ $(	for i in foo
158da2e3ebdSchin			do	${fun}fun
159da2e3ebdSchin				print $i
160da2e3ebdSchin			done
161da2e3ebdSchin		) != foo ]]
162da2e3ebdSchin	then	err_exit "$fun call in ${fun}fun breaks out of for loop"
163da2e3ebdSchin	fi
164da2e3ebdSchindone
165da2e3ebdSchinif	[[ $(print -f "%b" "\a\n\v\b\r\f\E\03\\oo") != $'\a\n\v\b\r\f\E\03\\oo' ]]
166da2e3ebdSchinthen	err_exit 'print -f "%b" not working'
167da2e3ebdSchinfi
1687c2fbfb3SApril Chinif	[[ $(print -f "%P" "[^x].*b\$") != '*[!x]*b' ]]
169da2e3ebdSchinthen	err_exit 'print -f "%P" not working'
170da2e3ebdSchinfi
171b30d1939SAndy Fiddamanif	[[ $(print -f "%(pattern)q" "[^x].*b\$") != '*[!x]*b' ]]
172b30d1939SAndy Fiddamanthen	err_exit 'print -f "%(pattern)q" not working'
173b30d1939SAndy Fiddamanfi
174da2e3ebdSchinif	[[ $(abc: for i in foo bar;do print $i;break abc;done) != foo ]]
175da2e3ebdSchinthen	err_exit 'break labels not working'
176da2e3ebdSchinfi
177da2e3ebdSchinif	[[ $(command -v if)	!= if ]]
178da2e3ebdSchinthen	err_exit	'command -v not working'
179da2e3ebdSchinfi
180da2e3ebdSchinread -r var <<\!
18134f9b3eeSRoland Mainz
182da2e3ebdSchin!
183da2e3ebdSchinif	[[ $var != "" ]]
184da2e3ebdSchinthen	err_exit "read -r of blank line not working"
185da2e3ebdSchinfi
18634f9b3eeSRoland Mainzmkdir -p $tmp/a/b/c 2>/dev/null || err_exit  "mkdir -p failed"
18734f9b3eeSRoland Mainz$SHELL -c "cd $tmp/a/b; cd c" 2>/dev/null || err_exit "initial script relative cd fails"
18834f9b3eeSRoland Mainz
18934f9b3eeSRoland Mainztrap 'print TERM' TERM
19034f9b3eeSRoland Mainzexp=$'trap -- \'print TERM\' TERM\ntrap -- \'cd /; rm -rf '$tmp$'\' EXIT'
19134f9b3eeSRoland Mainzgot=$(trap)
19234f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "\$(trap) failed -- expected \"$exp\", got \"$got\""
19334f9b3eeSRoland Mainzexp='print TERM'
19434f9b3eeSRoland Mainzgot=$(trap -p TERM)
19534f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "\$(trap -p TERM) failed -- expected \"$exp\", got \"$got\""
19634f9b3eeSRoland Mainz
1977c2fbfb3SApril Chin[[ $($SHELL -c 'trap "print ok" SIGTERM; kill -s SIGTERM $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized'
1987c2fbfb3SApril Chin[[ $($SHELL -c 'trap "print ok" sigterm; kill -s sigterm $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized'
1997c2fbfb3SApril Chin[[ $($SHELL -c '( trap "" TERM);kill $$;print bad' == bad) ]] 2> /dev/null && err_exit 'trap ignored in subshell causes it to be ignored by parent'
200da2e3ebdSchin${SHELL} -c 'kill -1 -$$' 2> /dev/null
20134f9b3eeSRoland Mainz[[ $(kill -l $?) == HUP ]] || err_exit 'kill -1 -pid not working'
202da2e3ebdSchin${SHELL} -c 'kill -1 -$$' 2> /dev/null
20334f9b3eeSRoland Mainz[[ $(kill -l $?) == HUP ]] || err_exit 'kill -n1 -pid not working'
204da2e3ebdSchin${SHELL} -c 'kill -s HUP -$$' 2> /dev/null
20534f9b3eeSRoland Mainz[[ $(kill -l $?) == HUP ]] || err_exit 'kill -HUP -pid not working'
206da2e3ebdSchinn=123
207da2e3ebdSchintypeset -A base
208da2e3ebdSchinbase[o]=8#
209da2e3ebdSchinbase[x]=16#
210da2e3ebdSchinbase[X]=16#
211da2e3ebdSchinfor i in d i o u x X
212da2e3ebdSchindo	if	(( $(( ${base[$i]}$(printf "%$i" $n) )) != n  ))
213da2e3ebdSchin	then	err_exit "printf %$i not working"
214da2e3ebdSchin	fi
215da2e3ebdSchindone
216*89af4c7bSAndy Fiddamanif	[[ $(printf -eexist) != -eexist ]]
217*89af4c7bSAndy Fiddamanthen	err_exit 'printf -eexist ... not working'
218*89af4c7bSAndy Fiddamanfi
219*89af4c7bSAndy Fiddamanif	[[ $(printf -- "%s" foo) != foo ]]
220*89af4c7bSAndy Fiddamanthen	err_exit 'printf -- not working'
221*89af4c7bSAndy Fiddamanfi
222*89af4c7bSAndy Fiddamanif	[[ $(printf -- --) != -- ]]
223*89af4c7bSAndy Fiddamanthen	err_exit 'printf -- -- ... not working'
224*89af4c7bSAndy Fiddamanfi
225*89af4c7bSAndy Fiddamanif	[[ $(printf -- -eexist) != -eexist ]]
226*89af4c7bSAndy Fiddamanthen	err_exit 'printf -- -eexist. not working'
227*89af4c7bSAndy Fiddamanfi
228da2e3ebdSchinif	[[ $( trap 'print done' EXIT) != done ]]
229da2e3ebdSchinthen	err_exit 'trap on EXIT not working'
230da2e3ebdSchinfi
231da2e3ebdSchinif	[[ $( trap 'print done' EXIT; trap - EXIT) == done ]]
232da2e3ebdSchinthen	err_exit 'trap on EXIT not being cleared'
233da2e3ebdSchinfi
234b30d1939SAndy Fiddamanif	[[ $(LC_MESSAGES=C type test) != 'test is a shell builtin' ]]
235da2e3ebdSchinthen	err_exit 'whence -v test not a builtin'
236da2e3ebdSchinfi
237da2e3ebdSchinbuiltin -d test
238da2e3ebdSchinif	[[ $(type test) == *builtin* ]]
239da2e3ebdSchinthen	err_exit 'whence -v test after builtin -d incorrect'
240da2e3ebdSchinfi
241da2e3ebdSchintypeset -Z3 percent=$(printf '%o\n' "'%'")
242da2e3ebdSchinforrmat=\\${percent}s
243da2e3ebdSchinif      [[ $(printf "$forrmat") != %s ]]
244da2e3ebdSchinthen    err_exit "printf $forrmat not working"
245da2e3ebdSchinfi
246da2e3ebdSchinif	(( $(printf 'x\0y' | wc -c) != 3 ))
247da2e3ebdSchinthen	err_exit 'printf \0 not working'
248da2e3ebdSchinfi
249da2e3ebdSchinif	[[ $(printf "%bx%s\n" 'f\to\cbar') != $'f\to' ]]
250da2e3ebdSchinthen	err_exit 'printf %bx%s\n  not working'
251da2e3ebdSchinfi
252da2e3ebdSchinalpha=abcdefghijklmnop
253da2e3ebdSchinif	[[ $(printf "%10.*s\n" 5 $alpha) != '     abcde' ]]
254da2e3ebdSchinthen	err_exit 'printf %10.%s\n  not working'
255da2e3ebdSchinfi
256da2e3ebdSchinfloat x2=.0000625
257da2e3ebdSchinif	[[ $(printf "%10.5E\n" x2) != 6.25000E-05 ]]
258da2e3ebdSchinthen	err_exit 'printf "%10.5E" not normalizing correctly'
259da2e3ebdSchinfi
260da2e3ebdSchinx2=.000000001
261da2e3ebdSchinif	[[ $(printf "%g\n" x2 2>/dev/null) != 1e-09 ]]
262da2e3ebdSchinthen	err_exit 'printf "%g" not working correctly'
263da2e3ebdSchinfi
264da2e3ebdSchin#FIXME#($SHELL read -s foobar <<\!
265da2e3ebdSchin#FIXME#testing
266da2e3ebdSchin#FIXME#!
267da2e3ebdSchin#FIXME#) 2> /dev/null || err_exit ksh read -s var fails
268da2e3ebdSchinif	[[ $(printf +3 2>/dev/null) !=   +3 ]]
269da2e3ebdSchinthen	err_exit 'printf is not processing formats beginning with + correctly'
270da2e3ebdSchinfi
271da2e3ebdSchinif	printf "%d %d\n" 123bad 78 >/dev/null 2>/dev/null
272da2e3ebdSchinthen	err_exit "printf not exiting non-zero with conversion errors"
273da2e3ebdSchinfi
274da2e3ebdSchinif	[[ $(trap --version 2> /dev/null;print done) != done ]]
275da2e3ebdSchinthen	err_exit 'trap builtin terminating after --version'
276da2e3ebdSchinfi
277da2e3ebdSchinif	[[ $(set --version 2> /dev/null;print done) != done ]]
278da2e3ebdSchinthen	err_exit 'set builtin terminating after --veresion'
279da2e3ebdSchinfi
280da2e3ebdSchinunset -f foobar
281da2e3ebdSchinfunction foobar
282da2e3ebdSchin{
283da2e3ebdSchin	print 'hello world'
284da2e3ebdSchin}
285da2e3ebdSchinOPTIND=1
286da2e3ebdSchinif	[[ $(getopts  $'[+?X\ffoobar\fX]' v --man 2>&1) != *'Xhello world'X* ]]
287da2e3ebdSchinthen	err_exit '\f...\f not working in getopts usage strings'
288da2e3ebdSchinfi
28934f9b3eeSRoland Mainzif	[[ $(printf '%H\n' $'<>"& \'\tabc') != '&lt;&gt;&quot;&amp;&nbsp;&apos;&#9;abc' ]]
290da2e3ebdSchinthen	err_exit 'printf %H not working'
291da2e3ebdSchinfi
292b30d1939SAndy Fiddamanif	[[ $(printf '%(html)q\n' $'<>"& \'\tabc') != '&lt;&gt;&quot;&amp;&nbsp;&apos;&#9;abc' ]]
293b30d1939SAndy Fiddamanthen	err_exit 'printf %(html)q not working'
294b30d1939SAndy Fiddamanfi
295b30d1939SAndy Fiddamanif	[[ $( printf 'foo://ab_c%(url)q\n' $'<>"& \'\tabc') != 'foo://ab_c%3C%3E%22%26%20%27%09abc' ]]
296b30d1939SAndy Fiddamanthen	err_exit 'printf %(url)q not working'
297b30d1939SAndy Fiddamanfi
29834f9b3eeSRoland Mainzif	[[ $(printf '%R %R %R %R\n' 'a.b' '*.c' '^'  '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]]
299b30d1939SAndy Fiddamanthen	err_exit 'printf %T not working'
300b30d1939SAndy Fiddamanfi
301b30d1939SAndy Fiddamanif	[[ $(printf '%(ere)q %(ere)q %(ere)q %(ere)q\n' 'a.b' '*.c' '^'  '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]]
302b30d1939SAndy Fiddamanthen	err_exit 'printf %(ere)q not working'
303da2e3ebdSchinfi
304da2e3ebdSchinif	[[ $(printf '%..:c\n' abc) != a:b:c ]]
30534f9b3eeSRoland Mainzthen	err_exit "printf '%..:c' not working"
306da2e3ebdSchinfi
307da2e3ebdSchinif	[[ $(printf '%..*c\n' : abc) != a:b:c ]]
30834f9b3eeSRoland Mainzthen	err_exit "printf '%..*c' not working"
309da2e3ebdSchinfi
310da2e3ebdSchinif	[[ $(printf '%..:s\n' abc def ) != abc:def ]]
31134f9b3eeSRoland Mainzthen	err_exit "printf '%..:s' not working"
312da2e3ebdSchinfi
313da2e3ebdSchinif	[[ $(printf '%..*s\n' : abc def) != abc:def ]]
31434f9b3eeSRoland Mainzthen	err_exit "printf '%..*s' not working"
315da2e3ebdSchinfi
316da2e3ebdSchin[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments'
317da2e3ebdSchin# we won't get hit by the one second boundary twice, right?
318da2e3ebdSchin[[ $(printf '%T\n' now) == "$(date)" ]] ||
319da2e3ebdSchin[[ $(printf '%T\n' now) == "$(date)" ]] ||
320da2e3ebdSchinerr_exit 'printf "%T" now'
321da2e3ebdSchinbehead()
322da2e3ebdSchin{
323da2e3ebdSchin	read line
324da2e3ebdSchin	left=$(cat)
325da2e3ebdSchin}
326da2e3ebdSchinprint $'line1\nline2' | behead
327da2e3ebdSchinif	[[ $left != line2 ]]
32834f9b3eeSRoland Mainzthen	err_exit "read reading ahead on a pipe"
329da2e3ebdSchinfi
33034f9b3eeSRoland Mainzread -n1 y <<!
33134f9b3eeSRoland Mainzabc
33234f9b3eeSRoland Mainz!
33334f9b3eeSRoland Mainzexp=a
33434f9b3eeSRoland Mainzif      [[ $y != $exp ]]
33534f9b3eeSRoland Mainzthen    err_exit "read -n1 failed -- expected '$exp', got '$y'"
33634f9b3eeSRoland Mainzfi
33734f9b3eeSRoland Mainzprint -n $'{ read -r line;print $line;}\nhello' > $tmp/script
33834f9b3eeSRoland Mainzchmod 755 $tmp/script
33934f9b3eeSRoland Mainzif	[[ $($SHELL < $tmp/script) != hello ]]
340da2e3ebdSchinthen	err_exit 'read of incomplete line not working correctly'
341da2e3ebdSchinfi
342da2e3ebdSchinset -f
343da2e3ebdSchinset -- *
344da2e3ebdSchinif      [[ $1 != '*' ]]
345da2e3ebdSchinthen    err_exit 'set -f not working'
346da2e3ebdSchinfi
347da2e3ebdSchinunset pid1 pid2
348da2e3ebdSchinfalse &
349da2e3ebdSchinpid1=$!
350da2e3ebdSchinpid2=$(
351da2e3ebdSchin	wait $pid1
352da2e3ebdSchin	(( $? == 127 )) || err_exit "job known to subshell"
353da2e3ebdSchin	print $!
354da2e3ebdSchin)
355da2e3ebdSchinwait $pid1
356da2e3ebdSchin(( $? == 1 )) || err_exit "wait not saving exit value"
357da2e3ebdSchinwait $pid2
358da2e3ebdSchin(( $? == 127 )) || err_exit "subshell job known to parent"
359da2e3ebdSchinenv=
36034f9b3eeSRoland Mainzv=$(getconf LIBPATH)
36134f9b3eeSRoland Mainzfor v in ${v//,/ }
36234f9b3eeSRoland Mainzdo	v=${v#*:}
36334f9b3eeSRoland Mainz	v=${v%%:*}
36434f9b3eeSRoland Mainz	eval [[ \$$v ]] && env="$env $v=\"\$$v\""
365da2e3ebdSchindone
366da2e3ebdSchinif	[[ $(foo=bar; eval foo=\$foo $env exec -c \$SHELL -c \'print \$foo\') != bar ]]
367da2e3ebdSchinthen	err_exit '"name=value exec -c ..." not working'
368da2e3ebdSchinfi
369da2e3ebdSchin$SHELL -c 'OPTIND=-1000000; getopts a opt -a' 2> /dev/null
370da2e3ebdSchin[[ $? == 1 ]] || err_exit 'getopts with negative OPTIND not working'
371da2e3ebdSchingetopts 'n#num' opt  -n 3
372da2e3ebdSchin[[ $OPTARG == 3 ]] || err_exit 'getopts with numerical arguments failed'
373da2e3ebdSchinif	[[ $($SHELL -c $'printf \'%2$s %1$s\n\' world hello') != 'hello world' ]]
374da2e3ebdSchinthen	err_exit 'printf %2$s %1$s not working'
375da2e3ebdSchinfi
3767c2fbfb3SApril Chinval=$(( 'C' ))
3777c2fbfb3SApril Chinset -- \
3787c2fbfb3SApril Chin	"'C"	$val	0	\
3797c2fbfb3SApril Chin	"'C'"	$val	0	\
3807c2fbfb3SApril Chin	'"C'	$val	0	\
3817c2fbfb3SApril Chin	'"C"'	$val	0	\
3827c2fbfb3SApril Chin	"'CX"	$val	1	\
3837c2fbfb3SApril Chin	"'CX'"	$val	1	\
3847c2fbfb3SApril Chin	"'C'X"	$val	1	\
3857c2fbfb3SApril Chin	'"CX'	$val	1	\
3867c2fbfb3SApril Chin	'"CX"'	$val	1	\
3877c2fbfb3SApril Chin	'"C"X'	$val	1
3887c2fbfb3SApril Chinwhile (( $# >= 3 ))
3897c2fbfb3SApril Chindo	arg=$1 val=$2 code=$3
3907c2fbfb3SApril Chin	shift 3
3917c2fbfb3SApril Chin	for fmt in '%d' '%g'
3927c2fbfb3SApril Chin	do	out=$(printf "$fmt" "$arg" 2>/dev/null)
3937c2fbfb3SApril Chin		err=$(printf "$fmt" "$arg" 2>&1 >/dev/null)
3947c2fbfb3SApril Chin		printf "$fmt" "$arg" >/dev/null 2>&1
3957c2fbfb3SApril Chin		ret=$?
39634f9b3eeSRoland Mainz		[[ $out == $val ]] || err_exit "printf $fmt $arg failed -- expected '$val', got '$out'"
3977c2fbfb3SApril Chin		if	(( $code ))
3987c2fbfb3SApril Chin		then	[[ $err ]] || err_exit "printf $fmt $arg failed, error message expected"
3997c2fbfb3SApril Chin		else	[[ $err ]] && err_exit "$err: printf $fmt $arg failed, error message not expected -- got '$err'"
4007c2fbfb3SApril Chin		fi
4017c2fbfb3SApril Chin		(( $ret == $code )) || err_exit "printf $fmt $arg failed -- expected exit code $code, got $ret"
4027c2fbfb3SApril Chin	done
4037c2fbfb3SApril Chindone
404da2e3ebdSchin((n=0))
405da2e3ebdSchin((n++)); ARGC[$n]=1 ARGV[$n]=""
406da2e3ebdSchin((n++)); ARGC[$n]=2 ARGV[$n]="-a"
407da2e3ebdSchin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2"
408da2e3ebdSchin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x"
409da2e3ebdSchin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x y"
410da2e3ebdSchinfor ((i=1; i<=n; i++))
411da2e3ebdSchindo	set -- ${ARGV[$i]}
412da2e3ebdSchin	OPTIND=0
413da2e3ebdSchin	while	getopts -a tst "av:" OPT
414da2e3ebdSchin	do	:
415da2e3ebdSchin	done
416da2e3ebdSchin	if	[[ $OPTIND != ${ARGC[$i]} ]]
4177c2fbfb3SApril Chin	then	err_exit "\$OPTIND after getopts loop incorrect -- expected ${ARGC[$i]}, got $OPTIND"
418da2e3ebdSchin	fi
419da2e3ebdSchindone
4207c2fbfb3SApril Chinoptions=ab:c
4217c2fbfb3SApril Chinoptarg=foo
4227c2fbfb3SApril Chinset -- -a -b $optarg -c bar
4237c2fbfb3SApril Chinwhile	getopts $options opt
4247c2fbfb3SApril Chindo	case $opt in
4257c2fbfb3SApril Chin	a|c)	[[ $OPTARG ]] && err_exit "getopts $options \$OPTARG for flag $opt failed, expected \"\", got \"$OPTARG\"" ;;
4267c2fbfb3SApril Chin	b)	[[ $OPTARG == $optarg ]] || err_exit "getopts $options \$OPTARG failed -- \"$optarg\" expected, got \"$OPTARG\"" ;;
4277c2fbfb3SApril Chin	*)	err_exit "getopts $options failed -- got flag $opt" ;;
4287c2fbfb3SApril Chin	esac
4297c2fbfb3SApril Chindone
43034f9b3eeSRoland Mainz
431b30d1939SAndy Fiddaman[[ $($SHELL 2> /dev/null -c 'readonly foo; getopts a: foo -a blah; echo foo') == foo ]] || err_exit 'getopts with readonly variable causes script to abort'
432b30d1939SAndy Fiddaman
43334f9b3eeSRoland Mainzunset a
43434f9b3eeSRoland Mainz{ read -N3 a; read -N1 b;}  <<!
43534f9b3eeSRoland Mainzabcdefg
43634f9b3eeSRoland Mainz!
43734f9b3eeSRoland Mainzexp=abc
43834f9b3eeSRoland Mainz[[ $a == $exp ]] || err_exit "read -N3 here-document failed -- expected '$exp', got '$a'"
43934f9b3eeSRoland Mainzexp=d
44034f9b3eeSRoland Mainz[[ $b == $exp ]] || err_exit "read -N1 here-document failed -- expected '$exp', got '$b'"
44134f9b3eeSRoland Mainzread -n3 a <<!
44234f9b3eeSRoland Mainzabcdefg
44334f9b3eeSRoland Mainz!
44434f9b3eeSRoland Mainzexp=abc
44534f9b3eeSRoland Mainz[[ $a == $exp ]] || err_exit "read -n3 here-document failed -- expected '$exp', got '$a'"
44634f9b3eeSRoland Mainz#(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;}
44734f9b3eeSRoland Mainz#[[ $a == $exp ]] || err_exit "read -N3 from pipe failed -- expected '$exp', got '$a'"
44834f9b3eeSRoland Mainz#exp=d
44934f9b3eeSRoland Mainz#[[ $b == $exp ]] || err_exit "read -N1 from pipe failed -- expected '$exp', got '$b'"
45034f9b3eeSRoland Mainz#(print -n a;sleep 1; print -n bcde) | read -n3 a
45134f9b3eeSRoland Mainz#exp=a
45234f9b3eeSRoland Mainz#[[ $a == $exp ]] || err_exit "read -n3 from pipe failed -- expected '$exp', got '$a'"
45334f9b3eeSRoland Mainz#rm -f $tmp/fifo
45434f9b3eeSRoland Mainz#if	mkfifo $tmp/fifo 2> /dev/null
45534f9b3eeSRoland Mainz#then	(print -n a; sleep 1;print -n bcde)  > $tmp/fifo &
45634f9b3eeSRoland Mainz#	{
45734f9b3eeSRoland Mainz#	read -u5 -n3 -t2 a || err_exit 'read -n3 from fifo timedout'
45834f9b3eeSRoland Mainz#	read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout'
45934f9b3eeSRoland Mainz#	} 5< $tmp/fifo
46034f9b3eeSRoland Mainz#	exp=a
46134f9b3eeSRoland Mainz#	[[ $a == $exp ]] || err_exit "read -n3 from fifo failed -- expected '$exp', got '$a'"
46234f9b3eeSRoland Mainz#	rm -f $tmp/fifo
46334f9b3eeSRoland Mainz#	mkfifo $tmp/fifo 2> /dev/null
46434f9b3eeSRoland Mainz#	(print -n a; sleep 1;print -n bcde) > $tmp/fifo &
46534f9b3eeSRoland Mainz#	{
46634f9b3eeSRoland Mainz#	read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out'
46734f9b3eeSRoland Mainz#	read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout'
46834f9b3eeSRoland Mainz#	} 5< $tmp/fifo
46934f9b3eeSRoland Mainz#	exp=abc
47034f9b3eeSRoland Mainz#	[[ $a == $exp ]] || err_exit "read -N3 from fifo failed -- expected '$exp', got '$a'"
47134f9b3eeSRoland Mainz#	exp=d
47234f9b3eeSRoland Mainz#	[[ $b == $exp ]] || err_exit "read -N1 from fifo failed -- expected '$exp', got '$b'"
47334f9b3eeSRoland Mainz#fi
47434f9b3eeSRoland Mainz#rm -f $tmp/fifo
47534f9b3eeSRoland Mainz
476da2e3ebdSchinfunction longline
477da2e3ebdSchin{
478da2e3ebdSchin	integer i
479da2e3ebdSchin	for((i=0; i < $1; i++))
480da2e3ebdSchin	do	print argument$i
481da2e3ebdSchin	done
482da2e3ebdSchin}
483da2e3ebdSchin# test command -x option
484da2e3ebdSchininteger sum=0 n=10000
485da2e3ebdSchinif	! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
486da2e3ebdSchinthen	for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) 2> /dev/null)
487da2e3ebdSchin	do	((sum += $i))
488da2e3ebdSchin	done
489da2e3ebdSchin	(( sum == n )) || err_exit "command -x processed only $sum arguments"
490da2e3ebdSchin	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
491da2e3ebdSchin	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
492da2e3ebdSchinfi
493da2e3ebdSchin# test command -x option with extra arguments
494da2e3ebdSchininteger sum=0 n=10000
495da2e3ebdSchinif      ! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
496da2e3ebdSchinthen    for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) one two three) #2> /dev/null)
497da2e3ebdSchin	do      ((sum += $i))
498da2e3ebdSchin	done
499da2e3ebdSchin	(( sum  > n )) || err_exit "command -x processed only $sum arguments"
500da2e3ebdSchin	(( (sum-n)%3==0 )) || err_exit "command -x processed only $sum arguments"
501da2e3ebdSchin	(( sum == n+3)) && err_exit "command -x processed only $sum arguments"
502da2e3ebdSchin	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
503da2e3ebdSchin	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
504da2e3ebdSchinfi
505da2e3ebdSchin# test for debug trap
506da2e3ebdSchin[[ $(typeset -i i=0
507da2e3ebdSchin	trap 'print $i' DEBUG
508da2e3ebdSchin	while (( i <2))
509da2e3ebdSchin	do	(( i++))
510da2e3ebdSchin	done) == $'0\n0\n1\n1\n2' ]]  || err_exit  "DEBUG trap not working"
511da2e3ebdSchingetconf UNIVERSE - ucb
512da2e3ebdSchin[[ $($SHELL -c 'echo -3') == -3 ]] || err_exit "echo -3 not working in ucb universe"
513da2e3ebdSchintypeset -F3 start_x=SECONDS total_t delay=0.02
514da2e3ebdSchintypeset reps=50 leeway=5
515b30d1939SAndy Fiddamansleep $(( 2 * leeway * reps * delay )) |
516b30d1939SAndy Fiddamanfor (( i=0 ; i < reps ; i++ ))
517b30d1939SAndy Fiddamando	read -N1 -t $delay
518b30d1939SAndy Fiddamandone
519b30d1939SAndy Fiddaman(( total_t = SECONDS - start_x ))
520b30d1939SAndy Fiddamanif	(( total_t > leeway * reps * delay ))
521b30d1939SAndy Fiddamanthen	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too long"
522b30d1939SAndy Fiddamanelif	(( total_t < reps * delay ))
523b30d1939SAndy Fiddamanthen	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too fast"
524b30d1939SAndy Fiddamanfi
525b30d1939SAndy Fiddaman$SHELL -c 'sleep $(printf "%a" .95)' 2> /dev/null || err_exit "sleep doesn't except %a format constants"
526b30d1939SAndy Fiddaman$SHELL -c 'test \( ! -e \)' 2> /dev/null ; [[ $? == 1 ]] || err_exit 'test \( ! -e \) not working'
5277c2fbfb3SApril Chin[[ $(ulimit) == "$(ulimit -fS)" ]] || err_exit 'ulimit is not the same as ulimit -fS'
52834f9b3eeSRoland Mainztmpfile=$tmp/file.2
5297c2fbfb3SApril Chinprint $'\nprint -r -- "${.sh.file} ${LINENO} ${.sh.lineno}"' > $tmpfile
5307c2fbfb3SApril Chin[[ $( . "$tmpfile") == "$tmpfile 2 1" ]] || err_exit 'dot command not working'
5317c2fbfb3SApril Chinprint -r -- "'xxx" > $tmpfile
5327c2fbfb3SApril Chin[[ $($SHELL -c ". $tmpfile"$'\n print ok' 2> /dev/null) == ok ]] || err_exit 'syntax error in dot command affects next command'
5337c2fbfb3SApril Chin
534b30d1939SAndy Fiddamanfloat sec=$SECONDS del=4
535b30d1939SAndy Fiddamanexec 3>&2 2>/dev/null
536b30d1939SAndy Fiddaman$SHELL -c "( sleep 1; kill -ALRM \$\$ ) & sleep $del" 2> /dev/null
537b30d1939SAndy Fiddamanexitval=$?
538b30d1939SAndy Fiddaman(( sec = SECONDS - sec ))
539b30d1939SAndy Fiddamanexec 2>&3-
540b30d1939SAndy Fiddaman(( exitval )) && err_exit "sleep doesn't exit 0 with ALRM interupt"
541b30d1939SAndy Fiddaman(( sec > (del - 1) )) || err_exit "ALRM signal causes sleep to terminate prematurely -- expected 3 sec, got $sec"
54234f9b3eeSRoland Mainztypeset -r z=3
54334f9b3eeSRoland Mainzy=5
54434f9b3eeSRoland Mainzfor i in 123 z  %x a.b.c
54534f9b3eeSRoland Mainzdo	( unset $i)  2>/dev/null && err_exit "unset $i should fail"
54634f9b3eeSRoland Mainzdone
54734f9b3eeSRoland Mainza=()
54834f9b3eeSRoland Mainzfor i in y y  y[8] t[abc] y.d a.b  a
54934f9b3eeSRoland Mainzdo	unset $i ||  print -u2  "err_exit unset $i should not fail"
55034f9b3eeSRoland Mainzdone
55134f9b3eeSRoland Mainz[[ $($SHELL -c 'y=3; unset 123 y;print $?$y') == 1 ]] 2> /dev/null ||  err_exit 'y is not getting unset with unset 123 y'
55234f9b3eeSRoland Mainz[[ $($SHELL -c 'trap foo TERM; (trap;(trap) )') == 'trap -- foo TERM' ]] || err_exit 'traps not getting reset when subshell is last process'
5537c2fbfb3SApril Chin
554b30d1939SAndy Fiddamann=$(printf "%b" 'a\0b\0c' | wc -c)
555b30d1939SAndy Fiddaman(( n == 5 )) || err_exit '\0 not working with %b format with printf'
556b30d1939SAndy Fiddaman
557b30d1939SAndy Fiddamant=$(ulimit -t)
558b30d1939SAndy Fiddaman[[ $($SHELL -c 'ulimit -v 15000 2>/dev/null; ulimit -t') == "$t" ]] || err_exit 'ulimit -v changes ulimit -t'
559b30d1939SAndy Fiddaman
560b30d1939SAndy Fiddaman$SHELL 2> /dev/null -c 'cd ""' && err_exit 'cd "" not producing an error'
561b30d1939SAndy Fiddaman[[ $($SHELL 2> /dev/null -c 'cd "";print hi') != hi ]] && err_exit 'cd "" should not terminate script'
562b30d1939SAndy Fiddaman
563b30d1939SAndy Fiddamanbincat=$(whence -p cat)
564b30d1939SAndy Fiddamanbuiltin cat
565b30d1939SAndy Fiddamanout=$tmp/seq.out
566b30d1939SAndy Fiddamanseq 11 >$out
567b30d1939SAndy Fiddamancmp -s <(print -- "$($bincat<( $bincat $out ) )") <(print -- "$(cat <( cat $out ) )") || err_exit "builtin cat differs from $bincat"
568b30d1939SAndy Fiddaman
569b30d1939SAndy Fiddaman[[ $($SHELL -c '{ printf %R "["; print ok;}' 2> /dev/null) == ok ]] || err_exit $'\'printf %R "["\' causes shell to abort'
570b30d1939SAndy Fiddaman
571b30d1939SAndy Fiddamanv=$( $SHELL -c $'
572b30d1939SAndy Fiddaman	trap \'print "usr1"\' USR1
573b30d1939SAndy Fiddaman	trap exit USR2
574b30d1939SAndy Fiddaman	sleep 1 && {
575b30d1939SAndy Fiddaman		kill -USR1 $$ && sleep 1
576b30d1939SAndy Fiddaman		kill -0 $$ 2>/dev/null && kill -USR2 $$
577b30d1939SAndy Fiddaman	} &
578b30d1939SAndy Fiddaman	sleep 2 | read
579b30d1939SAndy Fiddaman	echo done
580b30d1939SAndy Fiddaman' ) 2> /dev/null
581b30d1939SAndy Fiddaman[[ $v == $'usr1\ndone' ]] ||  err_exit 'read not terminating when receiving USR1 signal'
582b30d1939SAndy Fiddaman
583b30d1939SAndy Fiddamanmkdir $tmp/tmpdir1
584b30d1939SAndy Fiddamancd $tmp/tmpdir1
585b30d1939SAndy Fiddamanpwd=$PWD
586b30d1939SAndy Fiddamancd ../tmpdir1
587b30d1939SAndy Fiddaman[[ $PWD == "$pwd" ]] || err_exit 'cd ../tmpdir1 causes directory to change'
588b30d1939SAndy Fiddamancd "$pwd"
589b30d1939SAndy Fiddamanmv $tmp/tmpdir1 $tmp/tmpdir2
590b30d1939SAndy Fiddamancd ..  2> /dev/null || err_exit 'cannot change directory to .. after current directory has been renamed'
591b30d1939SAndy Fiddaman[[ $PWD == "$tmp" ]] || err_exit 'after "cd $tmp/tmpdir1; cd .." directory is not $tmp'
592b30d1939SAndy Fiddaman
593b30d1939SAndy Fiddamancd "$tmp"
594b30d1939SAndy Fiddamanmkdir $tmp/tmpdir2/foo
595b30d1939SAndy Fiddamanpwd=$PWD
596b30d1939SAndy Fiddamancd $tmp/tmpdir2/foo
597b30d1939SAndy Fiddamanmv $tmp/tmpdir2 $tmp/tmpdir1
598b30d1939SAndy Fiddamancd ../.. 2> /dev/null || err_exit 'cannot change directory to ../.. after current directory has been renamed'
599b30d1939SAndy Fiddaman[[ $PWD == "$tmp" ]] || err_exit 'after "cd $tmp/tmpdir2; cd ../.." directory is not $tmp'
600b30d1939SAndy Fiddamancd "$tmp"
601b30d1939SAndy Fiddamanrm -rf tmpdir1
602b30d1939SAndy Fiddaman
603b30d1939SAndy Fiddamancd /etc
604b30d1939SAndy Fiddamancd ..
605b30d1939SAndy Fiddaman[[ $(pwd) == / ]] || err_exit 'cd /etc;cd ..;pwd is not /'
606b30d1939SAndy Fiddamancd /etc
607b30d1939SAndy Fiddamancd ../..
608b30d1939SAndy Fiddaman[[ $(pwd) == / ]] || err_exit 'cd /etc;cd ../..;pwd is not /'
609b30d1939SAndy Fiddamancd /etc
610b30d1939SAndy Fiddamancd .././..
611b30d1939SAndy Fiddaman[[ $(pwd) == / ]] || err_exit 'cd /etc;cd .././..;pwd is not /'
612b30d1939SAndy Fiddamancd /usr/bin
613b30d1939SAndy Fiddamancd ../..
614b30d1939SAndy Fiddaman[[ $(pwd) == / ]] || err_exit 'cd /usr/bin;cd ../..;pwd is not /'
615b30d1939SAndy Fiddamancd /usr/bin
616b30d1939SAndy Fiddamancd ..
617b30d1939SAndy Fiddaman[[ $(pwd) == /usr ]] || err_exit 'cd /usr/bin;cd ..;pwd is not /usr'
618b30d1939SAndy Fiddamancd "$tmp"
619b30d1939SAndy Fiddamanif	mkdir $tmp/t1
620b30d1939SAndy Fiddamanthen	(
621b30d1939SAndy Fiddaman		cd $tmp/t1
622b30d1939SAndy Fiddaman		> real_t1
623b30d1939SAndy Fiddaman		(
624b30d1939SAndy Fiddaman			cd ..
625b30d1939SAndy Fiddaman			mv t1 t2
626b30d1939SAndy Fiddaman			mkdir t1
627b30d1939SAndy Fiddaman		)
628b30d1939SAndy Fiddaman		[[ -f real_t1 ]] || err_exit 'real_t1 not found after parent directory renamed in subshell'
629b30d1939SAndy Fiddaman	)
630b30d1939SAndy Fiddamanfi
631b30d1939SAndy Fiddamancd "$tmp"
632b30d1939SAndy Fiddaman
633b30d1939SAndy Fiddaman$SHELL +E -i <<- \! && err_exit 'interactive shell should not exit 0 after false'
634b30d1939SAndy Fiddaman	false
635b30d1939SAndy Fiddaman	exit
636b30d1939SAndy Fiddaman!
637b30d1939SAndy Fiddaman
638b30d1939SAndy Fiddamanif	kill -L > /dev/null 2>&1
639b30d1939SAndy Fiddamanthen	[[ $(kill -l HUP) == "$(kill -L HUP)" ]] || err_exit 'kill -l and kill -L are not the same when given a signal name'
640b30d1939SAndy Fiddaman	[[ $(kill -l 9) == "$(kill -L 9)" ]] || err_exit 'kill -l and kill -L are not the same when given a signal number'
641b30d1939SAndy Fiddaman	[[ $(kill -L) == *'9) KILL'* ]] || err_exit 'kill -L output does not contain 9) KILL'
642b30d1939SAndy Fiddamanfi
643b30d1939SAndy Fiddaman
644b30d1939SAndy Fiddamanunset ENV
645b30d1939SAndy Fiddamanv=$($SHELL 2> /dev/null +o rc -ic $'getopts a:bc: opt --man\nprint $?')
646b30d1939SAndy Fiddaman[[ $v == 2* ]] || err_exit 'getopts --man does not exit 2 for interactive shells'
647b30d1939SAndy Fiddaman
648b30d1939SAndy Fiddamanread baz <<< 'foo\\\\bar'
649b30d1939SAndy Fiddaman[[ $baz == 'foo\\bar' ]] || err_exit 'read of foo\\\\bar not getting foo\\bar'
650b30d1939SAndy Fiddaman
651b30d1939SAndy Fiddaman: ~root
652b30d1939SAndy Fiddaman[[ $(builtin) == *.sh.tilde* ]] &&  err_exit 'builtin contains .sh.tilde'
653b30d1939SAndy Fiddaman
654b30d1939SAndy Fiddamanexit $((Errors<125?Errors:125))
655