1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2014 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 <dgkorn@gmail.com> # 18# # 19######################################################################## 20 21unset HISTFILE 22export LC_ALL=C ENV= 23 24if [[ $( ${SHELL-ksh} -s hello<<-\! 25 print $1 26 ! 27 ) != hello ]] 28then 29 log_error "${SHELL-ksh} -s not working" 30fi 31 32x=$( 33 set -e 34 false && print bad 35 print good 36) 37if [[ $x != good ]] 38then 39 log_error 'sh -e not working' 40fi 41 42[[ $($SHELL -D -c 'print hi; print $"hello"') == '"hello"' ]] || log_error 'ksh -D not working' 43 44env=$TEST_DIR/.env 45print $'(print -u1 aha) &>/dev/null\n(print -u2 aha) &>/dev/null' > $env 46rc=$TEST_DIR/.kshrc 47print $'PS1=""\nfunction env_hit\n{\n\tprint OK\n}' > $rc 48 49export ENV=/.$env 50if [[ ! -o privileged ]] 51then 52 got=$($SHELL -E -c : 2>/dev/null) 53 if [[ $got ]] 54 then 55 got=$(printf %q "$got") 56 log_error "\$ENV file &>/dev/null does not redirect stdout -- expected '', got $got" 57 fi 58 59 got=$($SHELL -E -c : 2>&1 >/dev/null) 60 if [[ $got != *nonstandard* || $got == *$'\n'* ]] 61 then 62 got=$(printf %q "$got") 63 log_error "\$ENV file &>/dev/null does not redirect stderr -- expected one diagnostic line, got $got" 64 fi 65fi 66 67export ENV=/.$rc 68if [[ -o privileged ]] 69then 70 [[ $(print env_hit | $SHELL 2>&1) == "OK" ]] && 71 log_error 'privileged nointeractive shell reads $ENV file' 72 [[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] && 73 log_error 'privileged -E reads $ENV file' 74 [[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] && 75 log_error 'privileged +E reads $ENV file' 76 [[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] && 77 log_error 'privileged --rc reads $ENV file' 78 [[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] && 79 log_error 'privileged --norc reads $ENV file' 80else 81 [[ $(print env_hit | $SHELL 2>&1) == "OK" ]] && 82 log_error 'nointeractive shell reads $ENV file' 83 [[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] || 84 log_error '-E ignores $ENV file' 85 [[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] && 86 log_error '+E reads $ENV file' 87 [[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] || 88 log_error '--rc ignores $ENV file' 89 [[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] && 90 log_error '--norc reads $ENV file' 91 [[ $(print env_hit | $SHELL -i 2>&1) == "OK" ]] || 92 log_error '-i ignores $ENV file' 93fi 94 95export ENV= 96if [[ -o privileged ]] 97then 98 [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] && 99 log_error 'privileged nointeractive shell reads $HOME/.kshrc file' 100 [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] && 101 log_error 'privileged -E ignores empty $ENV' 102 [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] && 103 log_error 'privileged +E reads $HOME/.kshrc file' 104 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] && 105 log_error 'privileged --rc ignores empty $ENV' 106 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] && 107 log_error 'privileged --norc reads $HOME/.kshrc file' 108else 109 [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] && 110 log_error 'nointeractive shell reads $HOME/.kshrc file' 111 [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] && 112 log_error '-E ignores empty $ENV' 113 [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] && 114 log_error '+E reads $HOME/.kshrc file' 115 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] && 116 log_error '--rc ignores empty $ENV' 117 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] && 118 log_error '--norc reads $HOME/.kshrc file' 119fi 120 121unset ENV 122if [[ -o privileged ]] 123then 124 [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] && 125 log_error 'privileged nointeractive shell reads $HOME/.kshrc file' 126 [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] && 127 log_error 'privileged -E reads $HOME/.kshrc file' 128 [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] && 129 log_error 'privileged +E reads $HOME/.kshrc file' 130 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] && 131 log_error 'privileged --rc reads $HOME/.kshrc file' 132 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] && 133 log_error 'privileged --norc reads $HOME/.kshrc file' 134else 135 [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] && 136 log_error 'nointeractive shell reads $HOME/.kshrc file' 137 [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] || 138 log_error '-E ignores $HOME/.kshrc file' 139 [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] && 140 log_error '+E reads $HOME/.kshrc file' 141 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] || 142 log_error '--rc ignores $HOME/.kshrc file' 143 [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] && 144 log_error '--norc reads $HOME/.kshrc file' 145fi 146 147rm -rf $TEST_DIR/.kshrc 148 149if command set -G 2> /dev/null 150then 151 mkdir subdir 152 cd subdir 153 mkdir bar foo 154 > bar.c > bam.c 155 > bar/foo.c > bar/bam.c 156 > foo/bam.c 157 set -- **.c 158 expected='bam.c bar.c' 159 [[ $* == $expected ]] || 160 log_error '-G **.c failed' "$expected" "$*" 161 set -- ** 162 expected='bam.c bar bar.c bar/bam.c bar/foo.c foo foo/bam.c' 163 [[ $* == $expected ]] || 164 log_error '-G ** failed' "$expected" "$*" 165 set -- **/*.c 166 expected='bam.c bar.c bar/bam.c bar/foo.c foo/bam.c' 167 [[ $* == $expected ]] || 168 log_error '-G **/*.c failed' "$expected" "$*" 169 set -- **/bam.c 170 expected='bam.c bar/bam.c foo/bam.c' 171 [[ $* == $expected ]] || 172 log_error '-G **/bam.c failed' "$expected" "$*" 173 cd .. 174fi 175 176t="<$$>.profile.<$$>" 177echo "echo '$t'" > $HOME/.profile 178cp $SHELL ./-ksh 179if [[ -o privileged ]] 180then 181 actual=$($SHELL -l </dev/null 2>&1) 182 [[ "$actual" == *$t* ]] && 183 log_error 'privileged -l reads .profile' "*$t*" "$actual" 184 actual=$($SHELL --login </dev/null 2>&1) 185 [[ "$actual" == *$t* ]] && 186 log_error 'privileged --login reads .profile' "*$t*" "$actual" 187 actual=$($SHELL --login-shell </dev/null 2>&1) 188 [[ "$actual" == *$t* ]] && 189 log_error 'privileged --login-shell reads .profile' "*$t*" "$actual" 190 actual=$($SHELL --login_shell </dev/null 2>&1) 191 [[ "$actual" == *$t* ]] && 192 log_error 'privileged --login_shell reads .profile' "*$t*" "$actual" 193 actual=$(exec -a -ksh $SHELL </dev/null 2>&1) 194 [[ "$actual" == *$t* ]] && 195 log_error 'privileged exec -a -ksh ksh reads .profile' "*$t*" "$actual" 196 actual=$(./-ksh -i </dev/null 2>&1) 197 [[ "$actual" == *$t* ]] && 198 log_error 'privileged ./-ksh reads .profile' "*$t*" "$actual" 199 actual=$(./-ksh -ip </dev/null 2>&1) 200 [[ "$actual" == *$t* ]] && 201 log_error 'privileged ./-ksh -p reads .profile' "*$t*" "$actual" 202else 203 actual=$($SHELL -l </dev/null 2>&1) 204 [[ "$actual" == *$t* ]] || 205 log_error '-l ignores .profile' "*$t*" "$actual" 206 actual=$($SHELL --login </dev/null 2>&1) 207 [[ "$actual" == *$t* ]] || 208 log_error '--login ignores .profile' "*$t*" "$actual" 209 actual=$($SHELL --login-shell </dev/null 2>&1) 210 [[ "$actual" == *$t* ]] || 211 log_error '--login-shell ignores .profile' "*$t*" "$actual" 212 actual=$($SHELL --login_shell </dev/null 2>&1) 213 [[ "$actual" == *$t* ]] || 214 log_error '--login_shell ignores .profile' "*$t*" "$actual" 215 actual=$(exec -a -ksh $SHELL </dev/null 2>/dev/null) 216 [[ "$actual" == *$t* ]] || 217 log_error 'exec -a -ksh ksh 2>/dev/null ignores .profile' "*$t*" "$actual" 218 actual=$(exec -a -ksh $SHELL </dev/null 2>&1) 219 [[ "$actual" == *$t* ]] || 220 log_error 'exec -a -ksh ksh 2>&1 ignores .profile' "*$t*" "$actual" 221 actual=$(./-ksh -i </dev/null 2>&1) 222 [[ "$actual" == *$t* ]] || 223 log_error './-ksh ignores .profile' "*$t*" "$actual" 224 actual=$(./-ksh -ip </dev/null 2>&1) 225 [[ "$actual" == *$t* ]] && 226 log_error './-ksh -p does not ignore .profile' "*$t*" "$actual" 227fi 228 229cd ~- 230rm -rf $TEST_DIR/.profile 231 232# { exec interactive login_shell restricted xtrace } in the following test 233 234for opt in \ 235 allexport all-export all_export bgnice bg-nice bg_nice clobber emacs \ 236 errexit err-exit err_exit glob globstar glob-star glob_star gmacs \ 237 ignoreeof ignore-eof ignore_eof keyword log markdirs monitor notify \ 238 pipefail pipe-fail pipe_fail trackall track-all track_all \ 239 unset verbose vi viraw vi-raw vi_raw 240do 241 old=$opt 242 if [[ ! -o $opt ]] 243 then 244 old=no$opt 245 fi 246 247 set --$opt || log_error "set --$opt failed" 248 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 249 [[ -o no$opt ]] && log_error "[[ -o no$opt ]] failed" 250 [[ -o no-$opt ]] && log_error "[[ -o no-$opt ]] failed" 251 [[ -o no_$opt ]] && log_error "[[ -o no_$opt ]] failed" 252 [[ -o ?$opt ]] || log_error "[[ -o ?$opt ]] failed" 253 [[ -o ?no$opt ]] || log_error "[[ -o ?no$opt ]] failed" 254 [[ -o ?no-$opt ]] || log_error "[[ -o ?no-$opt ]] failed" 255 [[ -o ?no_$opt ]] || log_error "[[ -o ?no_$opt ]] failed" 256 257 set --no$opt || log_error "set --no$opt failed" 258 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 259 [[ -o $opt ]] && log_error "[[ -o $opt ]] failed" 260 261 set --no-$opt || log_error "set --no-$opt failed" 262 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 263 [[ -o $opt ]] && log_error "[[ -o $opt ]] failed" 264 265 set --no_$opt || log_error "set --no_$opt failed" 266 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 267 [[ -o $opt ]] && log_error "[[ -o $opt ]] failed" 268 269 set -o $opt || log_error "set -o $opt failed" 270 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 271 set -o $opt=1 || log_error "set -o $opt=1 failed" 272 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 273 set -o no$opt=0 || log_error "set -o no$opt=0 failed" 274 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 275 set --$opt=1 || log_error "set --$opt=1 failed" 276 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 277 set --no$opt=0 || log_error "set --no$opt=0 failed" 278 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 279 280 set -o no$opt || log_error "set -o no$opt failed" 281 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 282 set -o $opt=0 || log_error "set -o $opt=0 failed" 283 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 284 set -o no$opt=1 || log_error "set -o no$opt=1 failed" 285 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 286 set --$opt=0 || log_error "set --$opt=0 failed" 287 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 288 set --no$opt=1 || log_error "set --no$opt=1 failed" 289 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 290 291 set -o no-$opt || log_error "set -o no-$opt failed" 292 [[ -o no-$opt ]] || log_error "[[ -o no-$opt ]] failed" 293 294 set -o no_$opt || log_error "set -o no_$opt failed" 295 [[ -o no_$opt ]] || log_error "[[ -o no_$opt ]] failed" 296 297 set +o $opt || log_error "set +o $opt failed" 298 [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed" 299 300 set +o no$opt || log_error "set +o no$opt failed" 301 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 302 303 set +o no-$opt || log_error "set +o no-$opt failed" 304 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 305 306 set +o no_$opt || log_error "set +o no_$opt failed" 307 [[ -o $opt ]] || log_error "[[ -o $opt ]] failed" 308 309 set --$old 310done 311 312for opt in \ 313 exec interactive login_shell login-shell logi privileged \ 314 rc restricted xtrace 315do 316 [[ -o $opt ]] 317 y=$? 318 [[ -o no$opt ]] 319 n=$? 320 case $y$n in 321 10|01) ;; 322 *) log_error "[[ -o $opt ]] == [[ -o no$opt ]]" ;; 323 esac 324done 325 326for opt in \ 327 foo foo-bar foo_bar 328do 329 if [[ -o ?$opt ]] 330 then 331 log_error "[[ -o ?$opt ]] should fail" 332 fi 333 334 if [[ -o ?no$opt ]] 335 then 336 log_error "[[ -o ?no$opt ]] should fail" 337 fi 338done 339 340[[ $(set +o) == $(set --state) ]] || log_error "set --state different from set +o" 341set -- $(set --state) 342[[ $1 == set && $2 == --default ]] || log_error "set --state failed -- expected 'set --default *', got '$1 $2 *'" 343shift 344restore=$* 345shift 346off= 347for opt 348do 349 case $opt in 350 --not*) opt=${opt/--/--no} ;; 351 --no*) opt=${opt/--no/--} ;; 352 --*) opt=${opt/--/--no} ;; 353 esac 354 off="$off $opt" 355done 356set $off 357state=$(set --state) 358default=$(set --default --state) 359[[ $state == $default ]] || log_error "set --state for default options failed: expected '$default', got '$state'" 360set $restore 361state=$(set --state) 362[[ $state == "set $restore" ]] || log_error "set --state after restore failed: expected 'set $restore', got '$state'" 363 364typeset -a pipeline 365pipeline=( 366 ( nopipefail=0 pipefail=1 command='false|true|true' ) 367 ( nopipefail=0 pipefail=1 command='true|false|true' ) 368 ( nopipefail=1 pipefail=1 command='true|true|false' ) 369 ( nopipefail=1 pipefail=1 command='false|false|false' ) 370 ( nopipefail=0 pipefail=0 command='true|true|true' ) 371 ( nopipefail=0 pipefail=0 command='print hi|(sleep 1;/bin/cat)>/dev/null' ) 372) 373set --nopipefail 374for ((i = 0; i < ${#pipeline[@]}; i++ )) 375do 376 eval ${pipeline[i].command} 377 status=$? 378 expected=${pipeline[i].nopipefail} 379 [[ $status == $expected ]] || 380 log_error "--nopipefail '${pipeline[i].command}' exit status $status -- expected $expected" 381done 382ftt=0 383set --pipefail 384for ((i = 0; i < ${#pipeline[@]}; i++ )) 385do 386 eval ${pipeline[i].command} 387 status=$? 388 expected=${pipeline[i].pipefail} 389 if [[ $status != $expected ]] 390 then 391 log_error "--pipefail '${pipeline[i].command}' exit status $status -- expected $expected" 392 (( i == 0 )) && ftt=1 393 fi 394done 395 396if (( ! ftt )) 397then 398 exp=10 399 got=$(for((n=1;n<exp;n++))do $SHELL --pipefail -c '(sleep 0.1;false)|true|true' && break; done; print $n) 400 [[ $got == $exp ]] || log_error "--pipefail -c '(sleep 0.1;false)|true|true' fails with exit status 0 (after $got/$exp iterations)" 401fi 402 403for ((i=0; i < 20; i++)) 404do 405 if ! x=$(true | $bin_echo 123) 406 then 407 log_error 'command substitution with wrong exit status with pipefai' 408 break 409 fi 410done 411( 412 set -o pipefail 413 false | true 414 (( $? )) || log_error 'pipe not failing in subshell with pipefail' 415) | wc >/dev/null 416 417$SHELL -c 'set -o pipefail; false | $bin_true;' && log_error 'pipefail not returning failure with sh -c' 418exp='1212 or 1221' 419got=$( 420 set --pipefail 421 pipe() { date | cat > /dev/null ;} 422 print $'1\n2' | 423 while read i 424 do 425 if pipe $TEST_DIR 426 then 427 { print -n $i; sleep 2; print -n $i; } & 428 fi 429 done 430 wait 431) 432[[ $got == @((12|21)(12|21)) ]] || log_error "& job delayed by --pipefail, expected '$exp', got '$got'" 433$SHELL -c '[[ $- == *c* ]]' || log_error 'option c not in $-' 434> $TEST_DIR/.profile 435 436for i in i l r s D E a b e f h k n t u v x B C G H 437do 438 HOME=$TEST_DIR ENV= $SHELL -$i >/dev/null 2>&1 <<- ++EOF++ || log_error "option $i not in \$-" 439 [[ \$- == *$i* ]] || exit 1 440 ++EOF++ 441done 442 443letters=ilrabefhknuvxBCGE 444integer j=0 445for i in interactive login restricted allexport notify errexit \ 446 noglob trackall keyword noexec nounset verbose xtrace braceexpand \ 447 noclobber globstar rc 448do 449 HOME=$TEST_DIR ENV= $SHELL -o $i >/dev/null 2>&1 <<- ++EOF++ || log_error "option $i not equivalent to ${letters:j:1}" 450 [[ \$- == *${letters:j:1}* ]] || exit 1 451 ++EOF++ 452 ((j++)) 453done 454 455export ENV= PS1="(:$$:)" 456histfile=$TEST_DIR/history 457exp=$(HISTFILE=$histfile $SHELL -c $'function foo\n{\ncat\n}\ntype foo') 458for var in HISTSIZE HISTFILE 459do 460 got=$( ( HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ) 2>&1 ) 461 got=${got##*"$PS1"} 462 [[ $got == "$exp" ]] || log_error "function definition inside (...) with $var unset fails -- got '$got', expected '$exp'" 463 got=$( { HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ;} 2>&1 ) 464 got=${got##*"$PS1"} 465 [[ $got == "$exp" ]] || log_error "function definition inside {...;} with $var unset fails -- got '$got', expected '$exp'" 466done 467( unset HISTFILE; $SHELL -ic "HISTFILE=$histfile" 2>/dev/null ) || log_error "setting HISTFILE when not in environment fails" 468 469# the next tests loop on all combinations of 470# { SUB PAR CMD ADD } 471 472SUB=( 473 ( BEG='$( ' END=' )' ) 474 ( BEG='${ ' END='; }' ) 475) 476PAR=( 477 ( BEG='( ' END=' )' ) 478 ( BEG='{ ' END='; }' ) 479) 480CMD=( command-kill script-kill ) 481ADD=( '' '; :' ) 482 483cd $TEST_DIR 484print $'#!'$SHELL$'\nkill -KILL $$' > command-kill 485print $'kill -KILL $$' > script-kill 486chmod +x command-kill script-kill 487export PATH=.:$PATH 488exp='Killed' 489for ((S=0; S<${#SUB[@]}; S++)) 490do 491 for ((P=0; P<${#PAR[@]}; P++)) 492 do 493 for ((C=0; C<${#CMD[@]}; C++)) 494 do 495 for ((A=0; A<${#ADD[@]}; A++)) 496 do 497 cmd="${SUB[S].BEG}${PAR[P].BEG}${CMD[C]}${PAR[P].END} 2>&1${ADD[A]}${SUB[S].END}" 498 eval got="$cmd" 499 got=${got##*': '} 500 got=${got%%'('*} 501 [[ $got == "$exp" ]] || log_error "$cmd failed -- got '$got', expected '$exp'" 502 done 503 done 504 done 505done 506 507$SHELL 2> /dev/null -c '{; true ;}' || log_error 'leading ; causes syntax error in brace group' 508$SHELL 2> /dev/null -c '(; true ;)' || log_error 'leading ; causes syntax error in parenthesis group' 509 510print 'for ((i = 0; i < ${1:-10000}; i++ )); do printf "%.*c\n" 15 x; done' > pipefail 511chmod +x pipefail 512$SHELL --pipefail -c './pipefail 10000 | sed 1q' >/dev/null 2>&1 & 513tst=$! 514{ sleep 4; kill $tst; } 2>/dev/null & 515spy=$! 516wait $tst 2>/dev/null 517status=$? 518if [[ $status == 0 || $(kill -l $status) == PIPE ]] 519then 520 kill $spy 2>/dev/null 521else 522 log_error "pipefail pipeline bypasses SIGPIPE and hangs" 523fi 524 525wait 526 527[[ $($SHELL -uc '[[ "${d1.u[z asd].revents}" ]]' 2>&1) == *'d1.u[z asd].revents'* ]] || log_error 'name of unset parameter not in error message' 528 529[[ $($SHELL 2> /dev/null -xc $'set --showme\nprint 1\n; print 2') == 1 ]] || log_error 'showme option with xtrace not working correctly' 530 531$SHELL -uc 'var=foo;unset var;: ${var%foo}' >/dev/null 2>&1 && log_error '${var%foo} should fail with set -u' 532$SHELL -uc 'var=foo;unset var;: ${!var}' >/dev/null 2>&1 && log_error '${!var} should fail with set -u' 533$SHELL -uc 'var=foo;unset var;: ${#var}' >/dev/null 2>&1 && log_error '${#var} should fail with set -u' 534$SHELL -uc 'var=foo;unset var;: ${var-OK}' >/dev/null 2>&1 || log_error '${var-OK} should not fail with set -u' 535$SHELL -uc 'var=foo;nset var;: ${var:-OK}' >/dev/null 2>&1 || log_error '${var:-OK} should not fail with set -u' 536 537z=$($SHELL 2>&1 -uc 'print ${X23456789012345}') 538[[ $z == *X23456789012345:* ]] || log_error "error message garbled with set -u got $z" 539 540# pipe hang bug fixed 2011-03-15 541float start=SECONDS toolong=3 542( $SHELL <<-EOF 543 set -o pipefail 544 (sleep $toolong;kill \$\$> /dev/null) & 545 cat $SHELL | for ((i=0; i < 5; i++)) 546 do 547 date | wc > /dev/null 548 $SHELL -c 'read -N1' 549 done 550EOF 551) 2> /dev/null 552(( (SECONDS-start) > (toolong-0.5) )) && log_error "pipefail causes script to hang" 553 554# showme with arithmetic for loops 555$SHELL -n -c $'for((;1;))\ndo ; nothing\ndone' 2>/dev/null || log_error 'showme commands give syntax error inside arithmetic for loops' 556 557#set -x 558float t1=SECONDS 559set -o pipefail 560print | while read 561do 562 if { date | true;} ; true 563 then 564 sleep 2 & 565 fi 566done 567(( (SECONDS-t1) > .5 )) && log_error 'pipefail should not wait for background processes' 568 569# process source files from profiles as profile files 570print '. ./dotfile' > envfile 571print $'alias print=:\nprint foobar' > dotfile 572[[ $(ENV=$PWD/envfile $SHELL -i -c : 2>/dev/null) == foobar ]] && 573 log_error 'files source from profile does not process aliases correctly' 574 575# tests the set -m puts background jobs in separate process group 576Command=$Command LINENO=$LINENO $SHELL -m <<- \EOF 577 error_count=0 578 function log_error 579 { 580 print -u2 -n "\t" 581 print -u2 -r ${Command}[$LINENO]: "${@:1}" 582 ((error_count++)) 583 } 584 [[ $- == *m* ]] || log_error '$- does not contain m when monitor mode specified' 585 float t=SECONDS 586 sleep 2 & pid=$! 587 kill -KILL -$pid 2> /dev/null || log_error 'kill to background group failed' 588 wait 2> /dev/null 589 (( (SECONDS-t) > 1 )) && log_error 'kill did not kill background sleep' 590 exit $error_count 591EOF 592((error_count+=$?)) 593 594# ========== 595$SHELL 2> /dev/null <<- \EOF && log_error 'unset variable with set -u on does not terminate script' 596 set -e -u -o pipefail 597 ls | while read file 598 do 599 files[${#files[*]}]=$fil 600 done 601 exit 602EOF 603 604# ========== 605actual="$($SHELL -vc 'print yes' 2>&1)" 606expect="print yes" 607[[ "$actual" =~ .*"$expect".* ]] || log_error 'incorrect output from ksh -v' "$expect" "$actual" 608