1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2012 AT&T Intellectual Property # 5# and is licensed under the # 6# Eclipse Public License, Version 1.0 # 7# by AT&T Intellectual Property # 8# # 9# A copy of the License is available at # 10# http://www.eclipse.org/org/documents/epl-v10.html # 11# (with md5 checksum b35adb5213ca9657e911e9befb180842) # 12# # 13# Information and Software Systems Research # 14# AT&T Research # 15# Florham Park NJ # 16# # 17# David Korn <dgk@research.att.com> # 18# # 19######################################################################## 20function err_exit 21{ 22 print -u2 -n "\t" 23 print -u2 -r ${Command}[$1]: "${@:2}" 24 let Errors+=1 25} 26alias err_exit='err_exit $LINENO' 27 28Command=${0##*/} 29integer Errors=0 30 31tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 32trap "cd /; rm -rf $tmp" EXIT 33 34# test shell builtin commands 35builtin getconf 36: ${foo=bar} || err_exit ": failed" 37[[ $foo == bar ]] || err_exit ": side effects failed" 38set -- - foobar 39[[ $# == 2 && $1 == - && $2 == foobar ]] || err_exit "set -- - foobar failed" 40set -- -x foobar 41[[ $# == 2 && $1 == -x && $2 == foobar ]] || err_exit "set -- -x foobar failed" 42getopts :x: foo || err_exit "getopts :x: returns false" 43[[ $foo == x && $OPTARG == foobar ]] || err_exit "getopts :x: failed" 44OPTIND=1 45getopts :r:s var -r 46if [[ $var != : || $OPTARG != r ]] 47then err_exit "'getopts :r:s var -r' not working" 48fi 49OPTIND=1 50getopts :d#u OPT -d 16177 51if [[ $OPT != d || $OPTARG != 16177 ]] 52then err_exit "'getopts :d#u OPT=d OPTARG=16177' failed -- OPT=$OPT OPTARG=$OPTARG" 53fi 54OPTIND=1 55while getopts 'ab' option -a -b 56do [[ $OPTIND == $((OPTIND)) ]] || err_exit "OPTIND optimization bug" 57done 58 59USAGE=$'[-][S:server?Operate on the specified \asubservice\a:]:[subservice:=pmserver] 60 { 61 [p:pmserver] 62 [r:repserver] 63 [11:notifyd] 64 }' 65set pmser p rep r notifyd -11 66while (( $# > 1 )) 67do OPTIND=1 68 getopts "$USAGE" OPT -S $1 69 [[ $OPT == S && $OPTARG == $2 ]] || err_exit "OPT=$OPT OPTARG=$OPTARG -- expected OPT=S OPTARG=$2" 70 shift 2 71done 72 73false ${foo=bar} && err_exit "false failed" 74read <<! 75hello world 76! 77[[ $REPLY == 'hello world' ]] || err_exit "read builtin failed" 78print x:y | IFS=: read a b 79if [[ $a != x ]] 80then err_exit "IFS=: read ... not working" 81fi 82read <<! 83hello \ 84world 85! 86[[ $REPLY == 'hello world' ]] || err_exit "read continuation failed" 87read -d x <<! 88hello worldxfoobar 89! 90[[ $REPLY == 'hello world' ]] || err_exit "read builtin failed" 91read <<\! 92hello \ 93 world \ 94 95! 96[[ $REPLY == 'hello world' ]] || err_exit "read continuation2 failed" 97print "one\ntwo" | { read line 98 print $line | /bin/cat > /dev/null 99 read line 100} 101read <<\! 102\ 103a\ 104\ 105\ 106b 107! 108if [[ $REPLY != ab ]] 109then err_exit "read multiple continuation failed" 110fi 111if [[ $line != two ]] 112then err_exit "read from pipeline failed" 113fi 114line=two 115read line < /dev/null 116if [[ $line != "" ]] 117then err_exit "read from /dev/null failed" 118fi 119if [[ $(print -R -) != - ]] 120then err_exit "print -R not working correctly" 121fi 122if [[ $(print -- -) != - ]] 123then err_exit "print -- not working correctly" 124fi 125print -f "hello%nbar\n" size > /dev/null 126if (( size != 5 )) 127then err_exit "%n format of printf not working" 128fi 129print -n -u2 2>&1- 130[[ -w /dev/fd/1 ]] || err_exit "2<&1- with built-ins has side effects" 131x=$0 132if [[ $(eval 'print $0') != $x ]] 133then err_exit '$0 not correct for eval' 134fi 135$SHELL -c 'read x <<< hello' 2> /dev/null || err_exit 'syntax <<< not recognized' 136($SHELL -c 'read x[1] <<< hello') 2> /dev/null || err_exit 'read x[1] not working' 137unset x 138readonly x 139set -- $(readonly) 140if [[ " $@ " != *" x "* ]] 141then err_exit 'unset readonly variables are not displayed' 142fi 143if [[ $( for i in foo bar 144 do print $i 145 continue 10 146 done 147 ) != $'foo\nbar' ]] 148then err_exit 'continue breaks out of loop' 149fi 150(continue bad 2>/dev/null && err_exit 'continue bad should return an error') 151(break bad 2>/dev/null && err_exit 'break bad should return an error') 152(continue 0 2>/dev/null && err_exit 'continue 0 should return an error') 153(break 0 2>/dev/null && err_exit 'break 0 should return an error') 154breakfun() { break;} 155continuefun() { continue;} 156for fun in break continue 157do if [[ $( for i in foo 158 do ${fun}fun 159 print $i 160 done 161 ) != foo ]] 162 then err_exit "$fun call in ${fun}fun breaks out of for loop" 163 fi 164done 165if [[ $(print -f "%b" "\a\n\v\b\r\f\E\03\\oo") != $'\a\n\v\b\r\f\E\03\\oo' ]] 166then err_exit 'print -f "%b" not working' 167fi 168if [[ $(print -f "%P" "[^x].*b\$") != '*[!x]*b' ]] 169then err_exit 'print -f "%P" not working' 170fi 171if [[ $(print -f "%(pattern)q" "[^x].*b\$") != '*[!x]*b' ]] 172then err_exit 'print -f "%(pattern)q" not working' 173fi 174if [[ $(abc: for i in foo bar;do print $i;break abc;done) != foo ]] 175then err_exit 'break labels not working' 176fi 177if [[ $(command -v if) != if ]] 178then err_exit 'command -v not working' 179fi 180read -r var <<\! 181 182! 183if [[ $var != "" ]] 184then err_exit "read -r of blank line not working" 185fi 186mkdir -p $tmp/a/b/c 2>/dev/null || err_exit "mkdir -p failed" 187$SHELL -c "cd $tmp/a/b; cd c" 2>/dev/null || err_exit "initial script relative cd fails" 188 189trap 'print TERM' TERM 190exp=$'trap -- \'print TERM\' TERM\ntrap -- \'cd /; rm -rf '$tmp$'\' EXIT' 191got=$(trap) 192[[ $got == $exp ]] || err_exit "\$(trap) failed -- expected \"$exp\", got \"$got\"" 193exp='print TERM' 194got=$(trap -p TERM) 195[[ $got == $exp ]] || err_exit "\$(trap -p TERM) failed -- expected \"$exp\", got \"$got\"" 196 197[[ $($SHELL -c 'trap "print ok" SIGTERM; kill -s SIGTERM $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized' 198[[ $($SHELL -c 'trap "print ok" sigterm; kill -s sigterm $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized' 199[[ $($SHELL -c '( trap "" TERM);kill $$;print bad' == bad) ]] 2> /dev/null && err_exit 'trap ignored in subshell causes it to be ignored by parent' 200${SHELL} -c 'kill -1 -$$' 2> /dev/null 201[[ $(kill -l $?) == HUP ]] || err_exit 'kill -1 -pid not working' 202${SHELL} -c 'kill -1 -$$' 2> /dev/null 203[[ $(kill -l $?) == HUP ]] || err_exit 'kill -n1 -pid not working' 204${SHELL} -c 'kill -s HUP -$$' 2> /dev/null 205[[ $(kill -l $?) == HUP ]] || err_exit 'kill -HUP -pid not working' 206n=123 207typeset -A base 208base[o]=8# 209base[x]=16# 210base[X]=16# 211for i in d i o u x X 212do if (( $(( ${base[$i]}$(printf "%$i" $n) )) != n )) 213 then err_exit "printf %$i not working" 214 fi 215done 216if [[ $(printf -eexist) != -eexist ]] 217then err_exit 'printf -eexist ... not working' 218fi 219if [[ $(printf -- "%s" foo) != foo ]] 220then err_exit 'printf -- not working' 221fi 222if [[ $(printf -- --) != -- ]] 223then err_exit 'printf -- -- ... not working' 224fi 225if [[ $(printf -- -eexist) != -eexist ]] 226then err_exit 'printf -- -eexist. not working' 227fi 228if [[ $( trap 'print done' EXIT) != done ]] 229then err_exit 'trap on EXIT not working' 230fi 231if [[ $( trap 'print done' EXIT; trap - EXIT) == done ]] 232then err_exit 'trap on EXIT not being cleared' 233fi 234if [[ $(LC_MESSAGES=C type test) != 'test is a shell builtin' ]] 235then err_exit 'whence -v test not a builtin' 236fi 237builtin -d test 238if [[ $(type test) == *builtin* ]] 239then err_exit 'whence -v test after builtin -d incorrect' 240fi 241typeset -Z3 percent=$(printf '%o\n' "'%'") 242forrmat=\\${percent}s 243if [[ $(printf "$forrmat") != %s ]] 244then err_exit "printf $forrmat not working" 245fi 246if (( $(printf 'x\0y' | wc -c) != 3 )) 247then err_exit 'printf \0 not working' 248fi 249if [[ $(printf "%bx%s\n" 'f\to\cbar') != $'f\to' ]] 250then err_exit 'printf %bx%s\n not working' 251fi 252alpha=abcdefghijklmnop 253if [[ $(printf "%10.*s\n" 5 $alpha) != ' abcde' ]] 254then err_exit 'printf %10.%s\n not working' 255fi 256float x2=.0000625 257if [[ $(printf "%10.5E\n" x2) != 6.25000E-05 ]] 258then err_exit 'printf "%10.5E" not normalizing correctly' 259fi 260x2=.000000001 261if [[ $(printf "%g\n" x2 2>/dev/null) != 1e-09 ]] 262then err_exit 'printf "%g" not working correctly' 263fi 264#FIXME#($SHELL read -s foobar <<\! 265#FIXME#testing 266#FIXME#! 267#FIXME#) 2> /dev/null || err_exit ksh read -s var fails 268if [[ $(printf +3 2>/dev/null) != +3 ]] 269then err_exit 'printf is not processing formats beginning with + correctly' 270fi 271if printf "%d %d\n" 123bad 78 >/dev/null 2>/dev/null 272then err_exit "printf not exiting non-zero with conversion errors" 273fi 274if [[ $(trap --version 2> /dev/null;print done) != done ]] 275then err_exit 'trap builtin terminating after --version' 276fi 277if [[ $(set --version 2> /dev/null;print done) != done ]] 278then err_exit 'set builtin terminating after --veresion' 279fi 280unset -f foobar 281function foobar 282{ 283 print 'hello world' 284} 285OPTIND=1 286if [[ $(getopts $'[+?X\ffoobar\fX]' v --man 2>&1) != *'Xhello world'X* ]] 287then err_exit '\f...\f not working in getopts usage strings' 288fi 289if [[ $(printf '%H\n' $'<>"& \'\tabc') != '<>"& '	abc' ]] 290then err_exit 'printf %H not working' 291fi 292if [[ $(printf '%(html)q\n' $'<>"& \'\tabc') != '<>"& '	abc' ]] 293then err_exit 'printf %(html)q not working' 294fi 295if [[ $( printf 'foo://ab_c%(url)q\n' $'<>"& \'\tabc') != 'foo://ab_c%3C%3E%22%26%20%27%09abc' ]] 296then err_exit 'printf %(url)q not working' 297fi 298if [[ $(printf '%R %R %R %R\n' 'a.b' '*.c' '^' '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]] 299then err_exit 'printf %T not working' 300fi 301if [[ $(printf '%(ere)q %(ere)q %(ere)q %(ere)q\n' 'a.b' '*.c' '^' '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]] 302then err_exit 'printf %(ere)q not working' 303fi 304if [[ $(printf '%..:c\n' abc) != a:b:c ]] 305then err_exit "printf '%..:c' not working" 306fi 307if [[ $(printf '%..*c\n' : abc) != a:b:c ]] 308then err_exit "printf '%..*c' not working" 309fi 310if [[ $(printf '%..:s\n' abc def ) != abc:def ]] 311then err_exit "printf '%..:s' not working" 312fi 313if [[ $(printf '%..*s\n' : abc def) != abc:def ]] 314then err_exit "printf '%..*s' not working" 315fi 316[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments' 317# we won't get hit by the one second boundary twice, right? 318[[ $(printf '%T\n' now) == "$(date)" ]] || 319[[ $(printf '%T\n' now) == "$(date)" ]] || 320err_exit 'printf "%T" now' 321behead() 322{ 323 read line 324 left=$(cat) 325} 326print $'line1\nline2' | behead 327if [[ $left != line2 ]] 328then err_exit "read reading ahead on a pipe" 329fi 330read -n1 y <<! 331abc 332! 333exp=a 334if [[ $y != $exp ]] 335then err_exit "read -n1 failed -- expected '$exp', got '$y'" 336fi 337print -n $'{ read -r line;print $line;}\nhello' > $tmp/script 338chmod 755 $tmp/script 339if [[ $($SHELL < $tmp/script) != hello ]] 340then err_exit 'read of incomplete line not working correctly' 341fi 342set -f 343set -- * 344if [[ $1 != '*' ]] 345then err_exit 'set -f not working' 346fi 347unset pid1 pid2 348false & 349pid1=$! 350pid2=$( 351 wait $pid1 352 (( $? == 127 )) || err_exit "job known to subshell" 353 print $! 354) 355wait $pid1 356(( $? == 1 )) || err_exit "wait not saving exit value" 357wait $pid2 358(( $? == 127 )) || err_exit "subshell job known to parent" 359env= 360v=$(getconf LIBPATH) 361for v in ${v//,/ } 362do v=${v#*:} 363 v=${v%%:*} 364 eval [[ \$$v ]] && env="$env $v=\"\$$v\"" 365done 366if [[ $(foo=bar; eval foo=\$foo $env exec -c \$SHELL -c \'print \$foo\') != bar ]] 367then err_exit '"name=value exec -c ..." not working' 368fi 369$SHELL -c 'OPTIND=-1000000; getopts a opt -a' 2> /dev/null 370[[ $? == 1 ]] || err_exit 'getopts with negative OPTIND not working' 371getopts 'n#num' opt -n 3 372[[ $OPTARG == 3 ]] || err_exit 'getopts with numerical arguments failed' 373if [[ $($SHELL -c $'printf \'%2$s %1$s\n\' world hello') != 'hello world' ]] 374then err_exit 'printf %2$s %1$s not working' 375fi 376val=$(( 'C' )) 377set -- \ 378 "'C" $val 0 \ 379 "'C'" $val 0 \ 380 '"C' $val 0 \ 381 '"C"' $val 0 \ 382 "'CX" $val 1 \ 383 "'CX'" $val 1 \ 384 "'C'X" $val 1 \ 385 '"CX' $val 1 \ 386 '"CX"' $val 1 \ 387 '"C"X' $val 1 388while (( $# >= 3 )) 389do arg=$1 val=$2 code=$3 390 shift 3 391 for fmt in '%d' '%g' 392 do out=$(printf "$fmt" "$arg" 2>/dev/null) 393 err=$(printf "$fmt" "$arg" 2>&1 >/dev/null) 394 printf "$fmt" "$arg" >/dev/null 2>&1 395 ret=$? 396 [[ $out == $val ]] || err_exit "printf $fmt $arg failed -- expected '$val', got '$out'" 397 if (( $code )) 398 then [[ $err ]] || err_exit "printf $fmt $arg failed, error message expected" 399 else [[ $err ]] && err_exit "$err: printf $fmt $arg failed, error message not expected -- got '$err'" 400 fi 401 (( $ret == $code )) || err_exit "printf $fmt $arg failed -- expected exit code $code, got $ret" 402 done 403done 404((n=0)) 405((n++)); ARGC[$n]=1 ARGV[$n]="" 406((n++)); ARGC[$n]=2 ARGV[$n]="-a" 407((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2" 408((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x" 409((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x y" 410for ((i=1; i<=n; i++)) 411do set -- ${ARGV[$i]} 412 OPTIND=0 413 while getopts -a tst "av:" OPT 414 do : 415 done 416 if [[ $OPTIND != ${ARGC[$i]} ]] 417 then err_exit "\$OPTIND after getopts loop incorrect -- expected ${ARGC[$i]}, got $OPTIND" 418 fi 419done 420options=ab:c 421optarg=foo 422set -- -a -b $optarg -c bar 423while getopts $options opt 424do case $opt in 425 a|c) [[ $OPTARG ]] && err_exit "getopts $options \$OPTARG for flag $opt failed, expected \"\", got \"$OPTARG\"" ;; 426 b) [[ $OPTARG == $optarg ]] || err_exit "getopts $options \$OPTARG failed -- \"$optarg\" expected, got \"$OPTARG\"" ;; 427 *) err_exit "getopts $options failed -- got flag $opt" ;; 428 esac 429done 430 431[[ $($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' 432 433unset a 434{ read -N3 a; read -N1 b;} <<! 435abcdefg 436! 437exp=abc 438[[ $a == $exp ]] || err_exit "read -N3 here-document failed -- expected '$exp', got '$a'" 439exp=d 440[[ $b == $exp ]] || err_exit "read -N1 here-document failed -- expected '$exp', got '$b'" 441read -n3 a <<! 442abcdefg 443! 444exp=abc 445[[ $a == $exp ]] || err_exit "read -n3 here-document failed -- expected '$exp', got '$a'" 446#(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;} 447#[[ $a == $exp ]] || err_exit "read -N3 from pipe failed -- expected '$exp', got '$a'" 448#exp=d 449#[[ $b == $exp ]] || err_exit "read -N1 from pipe failed -- expected '$exp', got '$b'" 450#(print -n a;sleep 1; print -n bcde) | read -n3 a 451#exp=a 452#[[ $a == $exp ]] || err_exit "read -n3 from pipe failed -- expected '$exp', got '$a'" 453#rm -f $tmp/fifo 454#if mkfifo $tmp/fifo 2> /dev/null 455#then (print -n a; sleep 1;print -n bcde) > $tmp/fifo & 456# { 457# read -u5 -n3 -t2 a || err_exit 'read -n3 from fifo timedout' 458# read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout' 459# } 5< $tmp/fifo 460# exp=a 461# [[ $a == $exp ]] || err_exit "read -n3 from fifo failed -- expected '$exp', got '$a'" 462# rm -f $tmp/fifo 463# mkfifo $tmp/fifo 2> /dev/null 464# (print -n a; sleep 1;print -n bcde) > $tmp/fifo & 465# { 466# read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out' 467# read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout' 468# } 5< $tmp/fifo 469# exp=abc 470# [[ $a == $exp ]] || err_exit "read -N3 from fifo failed -- expected '$exp', got '$a'" 471# exp=d 472# [[ $b == $exp ]] || err_exit "read -N1 from fifo failed -- expected '$exp', got '$b'" 473#fi 474#rm -f $tmp/fifo 475 476function longline 477{ 478 integer i 479 for((i=0; i < $1; i++)) 480 do print argument$i 481 done 482} 483# test command -x option 484integer sum=0 n=10000 485if ! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null 2>&1 486then for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) 2> /dev/null) 487 do ((sum += $i)) 488 done 489 (( sum == n )) || err_exit "command -x processed only $sum arguments" 490 command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null 2>&1 491 [[ $? != 1 ]] && err_exit 'incorrect exit status for command -x' 492fi 493# test command -x option with extra arguments 494integer sum=0 n=10000 495if ! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null 2>&1 496then for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) one two three) #2> /dev/null) 497 do ((sum += $i)) 498 done 499 (( sum > n )) || err_exit "command -x processed only $sum arguments" 500 (( (sum-n)%3==0 )) || err_exit "command -x processed only $sum arguments" 501 (( sum == n+3)) && err_exit "command -x processed only $sum arguments" 502 command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null 2>&1 503 [[ $? != 1 ]] && err_exit 'incorrect exit status for command -x' 504fi 505# test for debug trap 506[[ $(typeset -i i=0 507 trap 'print $i' DEBUG 508 while (( i <2)) 509 do (( i++)) 510 done) == $'0\n0\n1\n1\n2' ]] || err_exit "DEBUG trap not working" 511getconf UNIVERSE - ucb 512[[ $($SHELL -c 'echo -3') == -3 ]] || err_exit "echo -3 not working in ucb universe" 513typeset -F3 start_x=SECONDS total_t delay=0.02 514typeset reps=50 leeway=5 515sleep $(( 2 * leeway * reps * delay )) | 516for (( i=0 ; i < reps ; i++ )) 517do read -N1 -t $delay 518done 519(( total_t = SECONDS - start_x )) 520if (( total_t > leeway * reps * delay )) 521then err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too long" 522elif (( total_t < reps * delay )) 523then err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too fast" 524fi 525$SHELL -c 'sleep $(printf "%a" .95)' 2> /dev/null || err_exit "sleep doesn't except %a format constants" 526$SHELL -c 'test \( ! -e \)' 2> /dev/null ; [[ $? == 1 ]] || err_exit 'test \( ! -e \) not working' 527[[ $(ulimit) == "$(ulimit -fS)" ]] || err_exit 'ulimit is not the same as ulimit -fS' 528tmpfile=$tmp/file.2 529print $'\nprint -r -- "${.sh.file} ${LINENO} ${.sh.lineno}"' > $tmpfile 530[[ $( . "$tmpfile") == "$tmpfile 2 1" ]] || err_exit 'dot command not working' 531print -r -- "'xxx" > $tmpfile 532[[ $($SHELL -c ". $tmpfile"$'\n print ok' 2> /dev/null) == ok ]] || err_exit 'syntax error in dot command affects next command' 533 534float sec=$SECONDS del=4 535exec 3>&2 2>/dev/null 536$SHELL -c "( sleep 1; kill -ALRM \$\$ ) & sleep $del" 2> /dev/null 537exitval=$? 538(( sec = SECONDS - sec )) 539exec 2>&3- 540(( exitval )) && err_exit "sleep doesn't exit 0 with ALRM interupt" 541(( sec > (del - 1) )) || err_exit "ALRM signal causes sleep to terminate prematurely -- expected 3 sec, got $sec" 542typeset -r z=3 543y=5 544for i in 123 z %x a.b.c 545do ( unset $i) 2>/dev/null && err_exit "unset $i should fail" 546done 547a=() 548for i in y y y[8] t[abc] y.d a.b a 549do unset $i || print -u2 "err_exit unset $i should not fail" 550done 551[[ $($SHELL -c 'y=3; unset 123 y;print $?$y') == 1 ]] 2> /dev/null || err_exit 'y is not getting unset with unset 123 y' 552[[ $($SHELL -c 'trap foo TERM; (trap;(trap) )') == 'trap -- foo TERM' ]] || err_exit 'traps not getting reset when subshell is last process' 553 554n=$(printf "%b" 'a\0b\0c' | wc -c) 555(( n == 5 )) || err_exit '\0 not working with %b format with printf' 556 557t=$(ulimit -t) 558[[ $($SHELL -c 'ulimit -v 15000 2>/dev/null; ulimit -t') == "$t" ]] || err_exit 'ulimit -v changes ulimit -t' 559 560$SHELL 2> /dev/null -c 'cd ""' && err_exit 'cd "" not producing an error' 561[[ $($SHELL 2> /dev/null -c 'cd "";print hi') != hi ]] && err_exit 'cd "" should not terminate script' 562 563bincat=$(whence -p cat) 564builtin cat 565out=$tmp/seq.out 566seq 11 >$out 567cmp -s <(print -- "$($bincat<( $bincat $out ) )") <(print -- "$(cat <( cat $out ) )") || err_exit "builtin cat differs from $bincat" 568 569[[ $($SHELL -c '{ printf %R "["; print ok;}' 2> /dev/null) == ok ]] || err_exit $'\'printf %R "["\' causes shell to abort' 570 571v=$( $SHELL -c $' 572 trap \'print "usr1"\' USR1 573 trap exit USR2 574 sleep 1 && { 575 kill -USR1 $$ && sleep 1 576 kill -0 $$ 2>/dev/null && kill -USR2 $$ 577 } & 578 sleep 2 | read 579 echo done 580' ) 2> /dev/null 581[[ $v == $'usr1\ndone' ]] || err_exit 'read not terminating when receiving USR1 signal' 582 583mkdir $tmp/tmpdir1 584cd $tmp/tmpdir1 585pwd=$PWD 586cd ../tmpdir1 587[[ $PWD == "$pwd" ]] || err_exit 'cd ../tmpdir1 causes directory to change' 588cd "$pwd" 589mv $tmp/tmpdir1 $tmp/tmpdir2 590cd .. 2> /dev/null || err_exit 'cannot change directory to .. after current directory has been renamed' 591[[ $PWD == "$tmp" ]] || err_exit 'after "cd $tmp/tmpdir1; cd .." directory is not $tmp' 592 593cd "$tmp" 594mkdir $tmp/tmpdir2/foo 595pwd=$PWD 596cd $tmp/tmpdir2/foo 597mv $tmp/tmpdir2 $tmp/tmpdir1 598cd ../.. 2> /dev/null || err_exit 'cannot change directory to ../.. after current directory has been renamed' 599[[ $PWD == "$tmp" ]] || err_exit 'after "cd $tmp/tmpdir2; cd ../.." directory is not $tmp' 600cd "$tmp" 601rm -rf tmpdir1 602 603cd /etc 604cd .. 605[[ $(pwd) == / ]] || err_exit 'cd /etc;cd ..;pwd is not /' 606cd /etc 607cd ../.. 608[[ $(pwd) == / ]] || err_exit 'cd /etc;cd ../..;pwd is not /' 609cd /etc 610cd .././.. 611[[ $(pwd) == / ]] || err_exit 'cd /etc;cd .././..;pwd is not /' 612cd /usr/bin 613cd ../.. 614[[ $(pwd) == / ]] || err_exit 'cd /usr/bin;cd ../..;pwd is not /' 615cd /usr/bin 616cd .. 617[[ $(pwd) == /usr ]] || err_exit 'cd /usr/bin;cd ..;pwd is not /usr' 618cd "$tmp" 619if mkdir $tmp/t1 620then ( 621 cd $tmp/t1 622 > real_t1 623 ( 624 cd .. 625 mv t1 t2 626 mkdir t1 627 ) 628 [[ -f real_t1 ]] || err_exit 'real_t1 not found after parent directory renamed in subshell' 629 ) 630fi 631cd "$tmp" 632 633$SHELL +E -i <<- \! && err_exit 'interactive shell should not exit 0 after false' 634 false 635 exit 636! 637 638if kill -L > /dev/null 2>&1 639then [[ $(kill -l HUP) == "$(kill -L HUP)" ]] || err_exit 'kill -l and kill -L are not the same when given a signal name' 640 [[ $(kill -l 9) == "$(kill -L 9)" ]] || err_exit 'kill -l and kill -L are not the same when given a signal number' 641 [[ $(kill -L) == *'9) KILL'* ]] || err_exit 'kill -L output does not contain 9) KILL' 642fi 643 644unset ENV 645v=$($SHELL 2> /dev/null +o rc -ic $'getopts a:bc: opt --man\nprint $?') 646[[ $v == 2* ]] || err_exit 'getopts --man does not exit 2 for interactive shells' 647 648read baz <<< 'foo\\\\bar' 649[[ $baz == 'foo\\bar' ]] || err_exit 'read of foo\\\\bar not getting foo\\bar' 650 651: ~root 652[[ $(builtin) == *.sh.tilde* ]] && err_exit 'builtin contains .sh.tilde' 653 654exit $((Errors<125?Errors:125)) 655