14887Schin######################################################################## 24887Schin# # 34887Schin# This software is part of the ast package # 4*12068SRoger.Faulkner@Oracle.COM# Copyright (c) 1982-2010 AT&T Intellectual Property # 54887Schin# and is licensed under the # 64887Schin# Common Public License, Version 1.0 # 78462SApril.Chin@Sun.COM# by AT&T Intellectual Property # 84887Schin# # 94887Schin# A copy of the License is available at # 104887Schin# http://www.opensource.org/licenses/cpl1.0.txt # 114887Schin# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 124887Schin# # 134887Schin# Information and Software Systems Research # 144887Schin# AT&T Research # 154887Schin# Florham Park NJ # 164887Schin# # 174887Schin# David Korn <dgk@research.att.com> # 184887Schin# # 194887Schin######################################################################## 204887Schinfunction err_exit 214887Schin{ 224887Schin print -u2 -n "\t" 234887Schin print -u2 -r ${Command}[$1]: "${@:2}" 244887Schin let Errors+=1 254887Schin} 264887Schinalias err_exit='err_exit $LINENO' 274887Schin 284887SchinCommand=${0##*/} 294887Schininteger Errors=0 3010898Sroland.mainz@nrubsig.org 3110898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 3210898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT 3310898Sroland.mainz@nrubsig.org 3410898Sroland.mainz@nrubsig.org# test basic file operations like redirection, pipes, file expansion 358462SApril.Chin@Sun.COMset -- \ 368462SApril.Chin@Sun.COM go+r 0000 \ 378462SApril.Chin@Sun.COM go-r 0044 \ 388462SApril.Chin@Sun.COM ug=r 0330 \ 398462SApril.Chin@Sun.COM go+w 0000 \ 408462SApril.Chin@Sun.COM go-w 0022 \ 418462SApril.Chin@Sun.COM ug=w 0550 \ 428462SApril.Chin@Sun.COM go+x 0000 \ 438462SApril.Chin@Sun.COM go-x 0011 \ 448462SApril.Chin@Sun.COM ug=x 0660 \ 458462SApril.Chin@Sun.COM go-rx 0055 \ 468462SApril.Chin@Sun.COM uo-wx 0303 \ 478462SApril.Chin@Sun.COM ug-rw 0660 \ 488462SApril.Chin@Sun.COM o= 0007 498462SApril.Chin@Sun.COMwhile (( $# >= 2 )) 508462SApril.Chin@Sun.COMdo umask 0 518462SApril.Chin@Sun.COM umask $1 528462SApril.Chin@Sun.COM g=$(umask) 538462SApril.Chin@Sun.COM [[ $g == $2 ]] || err_exit "umask 0; umask $1 failed -- expected $2, got $g" 548462SApril.Chin@Sun.COM shift 2 558462SApril.Chin@Sun.COMdone 564887Schinumask u=rwx,go=rx || err_exit "umask u=rws,go=rx failed" 574887Schinif [[ $(umask -S) != u=rwx,g=rx,o=rx ]] 584887Schinthen err_exit 'umask -S incorrect' 594887Schinfi 604887Schinpwd=$PWD 614887Schin[[ $SHELL != /* ]] && SHELL=$pwd/$SHELL 6210898Sroland.mainz@nrubsig.orgcd $tmp || { err_exit "cd $tmp failed"; exit 1; } 638462SApril.Chin@Sun.COMum=$(umask -S) 648462SApril.Chin@Sun.COM( umask 0777; > foobar ) 658462SApril.Chin@Sun.COMrm -f foobar 668462SApril.Chin@Sun.COM> foobar 678462SApril.Chin@Sun.COM[[ -r foobar ]] || err_exit 'umask not being restored after subshell' 688462SApril.Chin@Sun.COMumask "$um" 698462SApril.Chin@Sun.COMrm -f foobar 704887Schin# optimizer bug test 714887Schin> foobar 724887Schinfor i in 1 2 734887Schindo print foobar* 744887Schin rm -f foobar 7510898Sroland.mainz@nrubsig.orgdone > out 7610898Sroland.mainz@nrubsig.orgif [[ "$(<out)" != "foobar"$'\n'"foobar*" ]] 774887Schinthen print -u2 "optimizer bug with file expansion" 784887Schinfi 7910898Sroland.mainz@nrubsig.orgrm -f out foobar 804887Schinmkdir dir 814887Schinif [[ $(print */) != dir/ ]] 824887Schinthen err_exit 'file expansion with trailing / not working' 834887Schinfi 844887Schinif [[ $(print *) != dir ]] 854887Schinthen err_exit 'file expansion with single file not working' 864887Schinfi 874887Schinprint hi > .foo 884887Schinif [[ $(print *) != dir ]] 894887Schinthen err_exit 'file expansion leading . not working' 904887Schinfi 914887Schindate > dat1 || err_exit "date > dat1 failed" 924887Schintest -r dat1 || err_exit "dat1 is not readable" 934887Schinx=dat1 944887Schincat <$x > dat2 || err_exit "cat < $x > dat2 failed" 954887Schincat dat1 dat2 | cat | cat | cat > dat3 || err_exit "cat pipe failed" 964887Schincat > dat4 <<! 974887Schin$(date) 984887Schin! 994887Schincat dat1 dat2 | cat | cat | cat > dat5 & 1004887Schinwait $! 1014887Schinset -- dat* 1024887Schinif (( $# != 5 )) 1034887Schinthen err_exit "dat* matches only $# files" 1044887Schinfi 10510898Sroland.mainz@nrubsig.orgif (command > foo\\abc) 2> /dev/null 1064887Schinthen set -- foo* 1074887Schin if [[ $1 != 'foo\abc' ]] 1084887Schin then err_exit 'foo* does not match foo\abc' 1094887Schin fi 1104887Schinfi 1114887Schinif ( : > TT* && : > TTfoo ) 2>/dev/null 1124887Schinthen set -- TT* 1134887Schin if (( $# < 2 )) 1144887Schin then err_exit 'TT* not expanding when file TT* exists' 1154887Schin fi 1164887Schinfi 1174887Schincd ~- || err_exit "cd back failed" 11810898Sroland.mainz@nrubsig.orgcat > $tmp/script <<- ! 1194887Schin #! $SHELL 1204887Schin print -r -- \$0 1214887Schin! 12210898Sroland.mainz@nrubsig.orgchmod 755 $tmp/script 12310898Sroland.mainz@nrubsig.orgif [[ $($tmp/script) != "$tmp/script" ]] 1244887Schinthen err_exit '$0 not correct for #! script' 1254887Schinfi 1264887Schinbar=foo 1274887Schineval foo=\$bar 1284887Schinif [[ $foo != foo ]] 1294887Schinthen err_exit 'eval foo=\$bar not working' 1304887Schinfi 1314887Schinbar='foo=foo\ bar' 1324887Schineval $bar 1334887Schinif [[ $foo != 'foo bar' ]] 1344887Schinthen err_exit 'eval foo=\$bar, with bar="foo\ bar" not working' 1354887Schinfi 1364887Schincd /tmp 1374887Schincd ../../tmp || err_exit "cd ../../tmp failed" 1384887Schinif [[ $PWD != /tmp ]] 1394887Schinthen err_exit 'cd ../../tmp is not /tmp' 1404887Schinfi 1414887Schin( sleep 2; cat <<! 1424887Schinfoobar 1434887Schin! 14410898Sroland.mainz@nrubsig.org) | cat > $tmp/foobar & 1454887Schinwait $! 14610898Sroland.mainz@nrubsig.orgfoobar=$( < $tmp/foobar) 1474887Schinif [[ $foobar != foobar ]] 1484887Schinthen err_exit "$foobar is not foobar" 1494887Schinfi 1504887Schin{ 1514887Schin print foo 1524887Schin /bin/echo bar 1534887Schin print bam 15410898Sroland.mainz@nrubsig.org} > $tmp/foobar 15510898Sroland.mainz@nrubsig.orgif [[ $( < $tmp/foobar) != $'foo\nbar\nbam' ]] 15610898Sroland.mainz@nrubsig.orgthen err_exit "output file pointer not shared correctly" 1574887Schinfi 15810898Sroland.mainz@nrubsig.orgcat > $tmp/foobar <<\! 1594887Schin print foo 1604887Schin /bin/echo bar 1614887Schin print bam 1624887Schin! 16310898Sroland.mainz@nrubsig.orgchmod +x $tmp/foobar 16410898Sroland.mainz@nrubsig.orgif [[ $($tmp/foobar) != $'foo\nbar\nbam' ]] 16510898Sroland.mainz@nrubsig.orgthen err_exit "script not working" 1664887Schinfi 16710898Sroland.mainz@nrubsig.orgif [[ $($tmp/foobar | /bin/cat) != $'foo\nbar\nbam' ]] 16810898Sroland.mainz@nrubsig.orgthen err_exit "script | cat not working" 1694887Schinfi 17010898Sroland.mainz@nrubsig.orgif [[ $( $tmp/foobar) != $'foo\nbar\nbam' ]] 17110898Sroland.mainz@nrubsig.orgthen err_exit "output file pointer not shared correctly" 1724887Schinfi 17310898Sroland.mainz@nrubsig.orgrm -f $tmp/foobar 1744887Schinx=$( (print foo) ; (print bar) ) 1754887Schinif [[ $x != $'foo\nbar' ]] 1764887Schinthen err_exit " ( (print foo);(print bar ) failed" 1774887Schinfi 1784887Schinx=$( (/bin/echo foo) ; (print bar) ) 1794887Schinif [[ $x != $'foo\nbar' ]] 1804887Schinthen err_exit " ( (/bin/echo);(print bar ) failed" 1814887Schinfi 1824887Schinx=$( (/bin/echo foo) ; (/bin/echo bar) ) 1834887Schinif [[ $x != $'foo\nbar' ]] 1844887Schinthen err_exit " ( (/bin/echo);(/bin/echo bar ) failed" 1854887Schinfi 18610898Sroland.mainz@nrubsig.orgcat > $tmp/script <<\! 1874887Schinif [[ -p /dev/fd/0 ]] 1884887Schinthen builtin cat 1894887Schin cat - > /dev/null 1904887Schin [[ -p /dev/fd/0 ]] && print ok 1914887Schinelse print no 1924887Schinfi 1934887Schin! 19410898Sroland.mainz@nrubsig.orgchmod +x $tmp/script 19510898Sroland.mainz@nrubsig.orgcase $( (print) | $tmp/script;:) in 1964887Schinok) ;; 1974887Schinno) err_exit "[[ -p /dev/fd/0 ]] fails for standard input pipe" ;; 1984887Schin*) err_exit "builtin replaces standard input pipe" ;; 1994887Schinesac 20010898Sroland.mainz@nrubsig.orgprint 'print $0' > $tmp/script 20110898Sroland.mainz@nrubsig.orgprint ". $tmp/script" > $tmp/scriptx 20210898Sroland.mainz@nrubsig.orgchmod +x $tmp/scriptx 20310898Sroland.mainz@nrubsig.orgif [[ $($tmp/scriptx) != $tmp/scriptx ]] 2044887Schinthen err_exit '$0 not correct for . script' 2054887Schinfi 20610898Sroland.mainz@nrubsig.orgcd $tmp || { err_exit "cd $tmp failed"; exit 1; } 20710898Sroland.mainz@nrubsig.orgprint ./b > ./a; print ./c > b; print ./d > c; print ./e > d; print "echo \"hello there\"" > e 2084887Schinchmod 755 a b c d e 2094887Schinx=$(./a) 2104887Schinif [[ $x != "hello there" ]] 21110898Sroland.mainz@nrubsig.orgthen err_exit "nested scripts failed" 2124887Schinfi 2134887Schinx=$( (./a) | cat) 2144887Schinif [[ $x != "hello there" ]] 21510898Sroland.mainz@nrubsig.orgthen err_exit "scripts in subshells fail" 2164887Schinfi 2174887Schincd ~- || err_exit "cd back failed" 2184887Schinx=$( (/bin/echo foo) 2> /dev/null ) 2194887Schinif [[ $x != foo ]] 2204887Schinthen err_exit "subshell in command substitution fails" 2214887Schinfi 2224887Schinexec 1>&- 2234887Schinx=$(print hello) 2244887Schinif [[ $x != hello ]] 2254887Schinthen err_exit "command subsitution with stdout closed failed" 2264887Schinfi 2274887Schincd $pwd 2284887Schinx=$(cat <<\! | $SHELL 2294887Schin/bin/echo | /bin/cat 2304887Schin/bin/echo hello 2314887Schin! 2324887Schin) 2334887Schinif [[ $x != $'\n'hello ]] 2344887Schinthen err_exit "$SHELL not working when standard input is a pipe" 2354887Schinfi 2364887Schinx=$( (/bin/echo hello) 2> /dev/null ) 2374887Schinif [[ $x != hello ]] 2384887Schinthen err_exit "subshell in command substitution with 1 closed fails" 2394887Schinfi 24010898Sroland.mainz@nrubsig.orgcat > $tmp/script <<- \! 2414887Schinread line 2> /dev/null 2424887Schinprint done 2434887Schin! 24410898Sroland.mainz@nrubsig.orgif [[ $($SHELL $tmp/script <&-) != done ]] 2454887Schinthen err_exit "executing script with 0 closed fails" 2464887Schinfi 2474887Schintrap '' INT 24810898Sroland.mainz@nrubsig.orgcat > $tmp/script <<- \! 2494887Schintrap 'print bad' INT 2504887Schinkill -s INT $$ 2514887Schinprint good 2524887Schin! 25310898Sroland.mainz@nrubsig.orgchmod +x $tmp/script 25410898Sroland.mainz@nrubsig.orgif [[ $($SHELL $tmp/script) != good ]] 2554887Schinthen err_exit "traps ignored by parent not ignored" 2564887Schinfi 2574887Schintrap - INT 25810898Sroland.mainz@nrubsig.orgcat > $tmp/script <<- \! 2594887Schinread line 2604887Schin/bin/cat 2614887Schin! 26210898Sroland.mainz@nrubsig.orgif [[ $($SHELL $tmp/script <<! 2634887Schinone 2644887Schintwo 2654887Schin! 2664887Schin) != two ]] 2674887Schinthen err_exit "standard input not positioned correctly" 2684887Schinfi 2694887Schinword=$(print $'foo\nbar' | { read line; /bin/cat;}) 2704887Schinif [[ $word != bar ]] 2714887Schinthen err_exit "pipe to { read line; /bin/cat;} not working" 2724887Schinfi 2734887Schinword=$(print $'foo\nbar' | ( read line; /bin/cat) ) 2744887Schinif [[ $word != bar ]] 2754887Schinthen err_exit "pipe to ( read line; /bin/cat) not working" 2764887Schinfi 2774887Schinif [[ $(print x{a,b}y) != 'xay xby' ]] 2784887Schinthen err_exit 'brace expansion not working' 2794887Schinfi 2804887Schinif [[ $(for i in foo bar 2814887Schin do ( tgz=$(print $i) 2824887Schin print $tgz) 2834887Schin done) != $'foo\nbar' ]] 2844887Schinthen err_exit 'for loop subshell optimizer bug' 2854887Schinfi 2864887Schinunset a1 2874887Schinoptbug() 2884887Schin{ 2894887Schin set -A a1 foo bar bam 2904887Schin integer i 2914887Schin for ((i=0; i < 3; i++)) 2924887Schin do 2934887Schin (( ${#a1[@]} < 2 )) && return 0 2944887Schin set -- "${a1[@]}" 2954887Schin shift 2964887Schin set -A a1 -- "$@" 2974887Schin done 2984887Schin return 1 2994887Schin} 3004887Schinoptbug || err_exit 'array size optimzation bug' 3018462SApril.Chin@Sun.COMwait # not running --pipefail which would interfere with subsequent tests 3024887Schin: $(jobs -p) # required to clear jobs for next jobs -p (interactive side effect) 3034887Schinsleep 20 & 3048462SApril.Chin@Sun.COMpids=$! 3054887Schinif [[ $(jobs -p) != $! ]] 30610898Sroland.mainz@nrubsig.orgthen err_exit 'jobs -p not reporting a background job' 3074887Schinfi 3084887Schinsleep 20 & 3098462SApril.Chin@Sun.COMpids="$pids $!" 3104887Schinfoo() 3114887Schin{ 3124887Schin set -- $(jobs -p) 3134887Schin (( $# == 2 )) || err_exit "$# jobs not reported -- 2 expected" 3144887Schin} 3154887Schinfoo 3168462SApril.Chin@Sun.COMkill $pids 3178462SApril.Chin@Sun.COM 3188462SApril.Chin@Sun.COM[[ $( (trap 'print alarm' ALRM; sleep 4) & sleep 2; kill -ALRM $!; sleep 2; wait) == alarm ]] || err_exit 'ALRM signal not working' 3194887Schin[[ $($SHELL -c 'trap "" HUP; $SHELL -c "(sleep 2;kill -HUP $$)& sleep 4;print done"') != done ]] && err_exit 'ignored traps not being ignored' 3204887Schin[[ $($SHELL -c 'o=foobar; for x in foo bar; do (o=save);print $o;done' 2> /dev/null ) == $'foobar\nfoobar' ]] || err_exit 'for loop optimization subshell bug' 3214887Schincommand exec 3<> /dev/null 3224887Schinif cat /dev/fd/3 >/dev/null 2>&1 3234887Schinthen [[ $($SHELL -c 'cat <(print foo)' 2> /dev/null) == foo ]] || err_exit 'process substitution not working' 32410898Sroland.mainz@nrubsig.org [[ $($SHELL -c $'tee >(grep \'1$\' > '$tmp/scriptx$') > /dev/null <<- \!!! 3254887Schin line0 3264887Schin line1 3274887Schin line2 3284887Schin !!! 3294887Schin wait 33010898Sroland.mainz@nrubsig.org cat '$tmp/scriptx 2> /dev/null) == line1 ]] || err_exit '>() process substitution fails' 33110898Sroland.mainz@nrubsig.org > $tmp/scriptx 3324887Schin [[ $($SHELL -c $' 3334887Schin for i in 1 33410898Sroland.mainz@nrubsig.org do tee >(grep \'1$\' > '$tmp/scriptx$') > /dev/null <<- \!!! 3354887Schin line0 3364887Schin line1 3374887Schin line2 3384887Schin !!! 3394887Schin done 3404887Schin wait 34110898Sroland.mainz@nrubsig.org cat '$tmp/scriptx 2>> /dev/null) == line1 ]] || err_exit '>() process substitution fails in for loop' 3424887Schin [[ $({ $SHELL -c 'cat <(for i in x y z; do print $i; done)';} 2> /dev/null) == $'x\ny\nz' ]] || 3434887Schin err_exit 'process substitution of compound commands not working' 3444887Schinfi 3454887Schin[[ $($SHELL -r 'command -p :' 2>&1) == *restricted* ]] || err_exit 'command -p not restricted' 34610898Sroland.mainz@nrubsig.orgprint cat > $tmp/scriptx 34710898Sroland.mainz@nrubsig.orgchmod +x $tmp/scriptx 34810898Sroland.mainz@nrubsig.org[[ $($SHELL -c "print foo | $tmp/scriptx ;:" 2> /dev/null ) == foo ]] || err_exit 'piping into script fails' 3494887Schin[[ $($SHELL -c 'X=1;print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 1 ]] || err_exit 'x=1;${x:=$(..."...")} failure' 3504887Schin[[ $($SHELL -c 'print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 0 ]] || err_exit '${x:=$(..."...")} failure' 3518462SApril.Chin@Sun.COMexec 3<&- 3524887Schinif [[ -d /dev/fd && -w /dev/fd/3 ]] 3534887Schinthen [[ $(cat <(print hello) ) == hello ]] || err_exit "process substitution not working outside for or while loop" 3544887Schin $SHELL -c '[[ $(for i in 1;do cat <(print hello);done ) == hello ]]' 2> /dev/null|| err_exit "process substitution not working in for or while loop" 3554887Schinfi 3564887Schinexec 3> /dev/null 35710898Sroland.mainz@nrubsig.orgprint 'print foo "$@"' > $tmp/scriptx 35810898Sroland.mainz@nrubsig.org[[ $( print "($tmp/scriptx bar)" | $SHELL 2>/dev/null) == 'foo bar' ]] || err_exit 'script pipe to shell fails' 35910898Sroland.mainz@nrubsig.orgprint "#! $SHELL" > $tmp/scriptx 36010898Sroland.mainz@nrubsig.orgprint 'print -- $0' >> $tmp/scriptx 36110898Sroland.mainz@nrubsig.orgchmod +x $tmp/scriptx 36210898Sroland.mainz@nrubsig.org[[ $($tmp/scriptx) == $tmp/scriptx ]] || err_exit "\$0 is $0 instead of $tmp/scriptx" 36310898Sroland.mainz@nrubsig.orgcat > $tmp/scriptx <<- \EOF 3648462SApril.Chin@Sun.COM myfilter() { x=$(print ok | cat); print -r -- $SECONDS;} 3658462SApril.Chin@Sun.COM set -o pipefail 3668462SApril.Chin@Sun.COM sleep 3 | myfilter 3678462SApril.Chin@Sun.COMEOF 36810898Sroland.mainz@nrubsig.org(( $($SHELL $tmp/scriptx) > 2.0 )) && err_exit 'command substitution causes pipefail option to hang' 3694887Schinexec 3<&- 3704887Schin( typeset -r foo=bar) 2> /dev/null || err_exit 'readonly variables set in a subshell cannot unset' 3718462SApril.Chin@Sun.COM$SHELL -c 'x=${ print hello;}; [[ $x == hello ]]' 2> /dev/null || err_exit '${ command;} not supported' 3728462SApril.Chin@Sun.COM$SHELL 2> /dev/null <<- \EOF || err_exit 'multiline ${...} command substitution not supported' 3738462SApril.Chin@Sun.COM x=${ 3748462SApril.Chin@Sun.COM print hello 3758462SApril.Chin@Sun.COM } 3768462SApril.Chin@Sun.COM [[ $x == hello ]] 3778462SApril.Chin@Sun.COMEOF 3788462SApril.Chin@Sun.COM$SHELL 2> /dev/null <<- \EOF || err_exit '${...} command substitution with side effects not supported ' 3798462SApril.Chin@Sun.COM y=bye 3808462SApril.Chin@Sun.COM x=${ 3818462SApril.Chin@Sun.COM y=hello 3828462SApril.Chin@Sun.COM print hello 3838462SApril.Chin@Sun.COM } 3848462SApril.Chin@Sun.COM [[ $y == $x ]] 3858462SApril.Chin@Sun.COMEOF 3868462SApril.Chin@Sun.COM$SHELL 2> /dev/null <<- \EOF || err_exit 'nested ${...} command substitution not supported' 3878462SApril.Chin@Sun.COM x=${ 3888462SApril.Chin@Sun.COM print ${ print hello;} $(print world) 3898462SApril.Chin@Sun.COM } 3908462SApril.Chin@Sun.COM [[ $x == 'hello world' ]] 3918462SApril.Chin@Sun.COMEOF 3928462SApril.Chin@Sun.COM$SHELL 2> /dev/null <<- \EOF || err_exit 'terminating } is not a reserved word with ${ command }' 3938462SApril.Chin@Sun.COM x=${ { print -n } ; print -n hello ; } ; print ' world' } 3948462SApril.Chin@Sun.COM [[ $x == '}hello world' ]] 3958462SApril.Chin@Sun.COMEOF 3968462SApril.Chin@Sun.COM$SHELL 2> /dev/null <<- \EOF || err_exit '${ command;}xxx not working' 3978462SApril.Chin@Sun.COM f() 3988462SApril.Chin@Sun.COM { 3998462SApril.Chin@Sun.COM print foo 4008462SApril.Chin@Sun.COM } 4018462SApril.Chin@Sun.COM [[ ${ f;}bar == foobar ]] 4028462SApril.Chin@Sun.COMEOF 4038462SApril.Chin@Sun.COM 4048462SApril.Chin@Sun.COMunset foo 40510898Sroland.mainz@nrubsig.org[[ ! ${foo[@]} ]] || err_exit '${foo[@]} is not empty when foo is unset' 40610898Sroland.mainz@nrubsig.org[[ ! ${foo[3]} ]] || err_exit '${foo[3]} is not empty when foo is unset' 4078462SApril.Chin@Sun.COM[[ $(print "[${ print foo }]") == '[foo]' ]] || err_exit '${...} not working when } is followed by ]' 4088462SApril.Chin@Sun.COM[[ $(print "${ print "[${ print foo }]" }") == '[foo]' ]] || err_exit 'nested ${...} not working when } is followed by ]' 4098462SApril.Chin@Sun.COMunset foo 4108462SApril.Chin@Sun.COMfoo=$(false) > /dev/null && err_exit 'failed command substitution with redirection not returning false' 4118462SApril.Chin@Sun.COMexpected=foreback 4128462SApril.Chin@Sun.COMgot=$(print -n fore;(sleep 2;print back)&) 4138462SApril.Chin@Sun.COM[[ $got == $expected ]] || err_exit "command substitution background process output error -- got '$got', expected '$expected'" 4148462SApril.Chin@Sun.COM 41510898Sroland.mainz@nrubsig.orgbinfalse=$(whence -p false) 41610898Sroland.mainz@nrubsig.orgfor false in false $binfalse 4178462SApril.Chin@Sun.COMdo x=$($false) && err_exit "x=\$($false) should fail" 4188462SApril.Chin@Sun.COM $($false) && err_exit "\$($false) should fail" 4198462SApril.Chin@Sun.COM $($false) > /dev/null && err_exit "\$($false) > /dev/null should fail" 4208462SApril.Chin@Sun.COMdone 42110898Sroland.mainz@nrubsig.orgif env x-a=y >/dev/null 2>&1 42210898Sroland.mainz@nrubsig.orgthen [[ $(env 'x-a=y' $SHELL -c 'env | grep x-a') == *x-a=y* ]] || err_exit 'invalid environment variables not preserved' 42310898Sroland.mainz@nrubsig.orgfi 42410898Sroland.mainz@nrubsig.orgfloat s=SECONDS 42510898Sroland.mainz@nrubsig.orgsleep=$(whence -p sleep) 42610898Sroland.mainz@nrubsig.orgfor i in 1 2 42710898Sroland.mainz@nrubsig.orgdo print $i 42810898Sroland.mainz@nrubsig.orgdone | while read sec; do ( $sleep $sec; $sleep $sec) done 42910898Sroland.mainz@nrubsig.org(( (SECONDS-s) < 4)) && err_exit '"command | while read...done" finishing too fast' 43010898Sroland.mainz@nrubsig.orgs=SECONDS 43110898Sroland.mainz@nrubsig.orgset -o pipefail 43210898Sroland.mainz@nrubsig.orgfor ((i=0; i < 30; i++)) 43310898Sroland.mainz@nrubsig.orgdo print hello 43410898Sroland.mainz@nrubsig.org sleep .1 43510898Sroland.mainz@nrubsig.orgdone | $sleep 1 43610898Sroland.mainz@nrubsig.org(( (SECONDS-s) < 2 )) || err_exit 'early termination not causing broken pipe' 43710898Sroland.mainz@nrubsig.org[[ $({ trap 'print trap' 0; print -n | $(whence -p cat); } & wait $!) == trap ]] || err_exit 'trap on exit not getting triggered' 43810898Sroland.mainz@nrubsig.orgvar=$({ trap 'print trap' ERR; print -n | $binfalse; } & wait $!) 43910898Sroland.mainz@nrubsig.org[[ $var == trap ]] || err_exit 'trap on ERR not getting triggered' 44010898Sroland.mainz@nrubsig.org 44110898Sroland.mainz@nrubsig.orgexp= 44210898Sroland.mainz@nrubsig.orggot=$( 44310898Sroland.mainz@nrubsig.org function fun 44410898Sroland.mainz@nrubsig.org { 44510898Sroland.mainz@nrubsig.org $binfalse && echo FAILED 44610898Sroland.mainz@nrubsig.org } 44710898Sroland.mainz@nrubsig.org : works if this line deleted : | 44810898Sroland.mainz@nrubsig.org fun 44910898Sroland.mainz@nrubsig.org : works if this line deleted : 45010898Sroland.mainz@nrubsig.org) 45110898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "pipe to function with conditional fails -- expected '$exp', got '$got'" 45210898Sroland.mainz@nrubsig.orggot=$( 45310898Sroland.mainz@nrubsig.org : works if this line deleted : | 45410898Sroland.mainz@nrubsig.org { $binfalse && echo FAILED; } 45510898Sroland.mainz@nrubsig.org : works if this line deleted : 45610898Sroland.mainz@nrubsig.org) 45710898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "pipe to { ... } with conditional fails -- expected '$exp', got '$got'" 45810898Sroland.mainz@nrubsig.org 45910898Sroland.mainz@nrubsig.orggot=$( 46010898Sroland.mainz@nrubsig.org : works if this line deleted : | 46110898Sroland.mainz@nrubsig.org ( $binfalse && echo FAILED ) 46210898Sroland.mainz@nrubsig.org : works if this line deleted : 46310898Sroland.mainz@nrubsig.org) 46410898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "pipe to ( ... ) with conditional fails -- expected '$exp', got '$got'" 46510898Sroland.mainz@nrubsig.org 46610898Sroland.mainz@nrubsig.org( $SHELL -c 'trap : DEBUG; x=( $foo); exit 0') 2> /dev/null || err_exit 'trap DEBUG fails' 46710898Sroland.mainz@nrubsig.org 468*12068SRoger.Faulkner@Oracle.COMtrue=$(whence -p true) 469*12068SRoger.Faulkner@Oracle.COMset -o pipefail 470*12068SRoger.Faulkner@Oracle.COMfloat start=$SECONDS end 471*12068SRoger.Faulkner@Oracle.COMfor ((i=0; i < 2; i++)) 472*12068SRoger.Faulkner@Oracle.COMdo print foo 473*12068SRoger.Faulkner@Oracle.COM sleep 1.5 474*12068SRoger.Faulkner@Oracle.COMdone | { read; $true; end=$SECONDS ;} 475*12068SRoger.Faulkner@Oracle.COM(( (SECONDS-start) < 1 )) && err_exit "pipefail not waiting for pipe to finish" 476*12068SRoger.Faulkner@Oracle.COMset +o pipefail 477*12068SRoger.Faulkner@Oracle.COM(( (SECONDS-start) > 2 )) && err_exit "pipefail causing /bin/true to wait for other end of pipe" 478*12068SRoger.Faulkner@Oracle.COM 479*12068SRoger.Faulkner@Oracle.COM 480*12068SRoger.Faulkner@Oracle.COM{ env A__z=C+SHLVL $SHELL -c : ;} 2> /dev/null || err_exit "SHLVL with wrong attribute fails" 481*12068SRoger.Faulkner@Oracle.COM 4824887Schinexit $((Errors)) 483